162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/init.h> 362306a36Sopenharmony_ci#include <linux/mm.h> 462306a36Sopenharmony_ci#include <linux/security.h> 562306a36Sopenharmony_ci#include <linux/sysctl.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci/* amount of vm to protect from userspace access by both DAC and the LSM*/ 862306a36Sopenharmony_ciunsigned long mmap_min_addr; 962306a36Sopenharmony_ci/* amount of vm to protect from userspace using CAP_SYS_RAWIO (DAC) */ 1062306a36Sopenharmony_ciunsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; 1162306a36Sopenharmony_ci/* amount of vm to protect from userspace using the LSM = CONFIG_LSM_MMAP_MIN_ADDR */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * Update mmap_min_addr = max(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR) 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_cistatic void update_mmap_min_addr(void) 1762306a36Sopenharmony_ci{ 1862306a36Sopenharmony_ci#ifdef CONFIG_LSM_MMAP_MIN_ADDR 1962306a36Sopenharmony_ci if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR) 2062306a36Sopenharmony_ci mmap_min_addr = dac_mmap_min_addr; 2162306a36Sopenharmony_ci else 2262306a36Sopenharmony_ci mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR; 2362306a36Sopenharmony_ci#else 2462306a36Sopenharmony_ci mmap_min_addr = dac_mmap_min_addr; 2562306a36Sopenharmony_ci#endif 2662306a36Sopenharmony_ci} 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* 2962306a36Sopenharmony_ci * sysctl handler which just sets dac_mmap_min_addr = the new value and then 3062306a36Sopenharmony_ci * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_ciint mmap_min_addr_handler(struct ctl_table *table, int write, 3362306a36Sopenharmony_ci void *buffer, size_t *lenp, loff_t *ppos) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci int ret; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci if (write && !capable(CAP_SYS_RAWIO)) 3862306a36Sopenharmony_ci return -EPERM; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci update_mmap_min_addr(); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci return ret; 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic int __init init_mmap_min_addr(void) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci update_mmap_min_addr(); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci return 0; 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_cipure_initcall(init_mmap_min_addr); 54