18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/init.h> 38c2ecf20Sopenharmony_ci#include <linux/mm.h> 48c2ecf20Sopenharmony_ci#include <linux/security.h> 58c2ecf20Sopenharmony_ci#include <linux/sysctl.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci/* amount of vm to protect from userspace access by both DAC and the LSM*/ 88c2ecf20Sopenharmony_ciunsigned long mmap_min_addr; 98c2ecf20Sopenharmony_ci/* amount of vm to protect from userspace using CAP_SYS_RAWIO (DAC) */ 108c2ecf20Sopenharmony_ciunsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; 118c2ecf20Sopenharmony_ci/* amount of vm to protect from userspace using the LSM = CONFIG_LSM_MMAP_MIN_ADDR */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * Update mmap_min_addr = max(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR) 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_cistatic void update_mmap_min_addr(void) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci#ifdef CONFIG_LSM_MMAP_MIN_ADDR 198c2ecf20Sopenharmony_ci if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR) 208c2ecf20Sopenharmony_ci mmap_min_addr = dac_mmap_min_addr; 218c2ecf20Sopenharmony_ci else 228c2ecf20Sopenharmony_ci mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR; 238c2ecf20Sopenharmony_ci#else 248c2ecf20Sopenharmony_ci mmap_min_addr = dac_mmap_min_addr; 258c2ecf20Sopenharmony_ci#endif 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/* 298c2ecf20Sopenharmony_ci * sysctl handler which just sets dac_mmap_min_addr = the new value and then 308c2ecf20Sopenharmony_ci * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ciint mmap_min_addr_handler(struct ctl_table *table, int write, 338c2ecf20Sopenharmony_ci void *buffer, size_t *lenp, loff_t *ppos) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci int ret; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci if (write && !capable(CAP_SYS_RAWIO)) 388c2ecf20Sopenharmony_ci return -EPERM; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci update_mmap_min_addr(); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci return ret; 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic int __init init_mmap_min_addr(void) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci update_mmap_min_addr(); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci return 0; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_cipure_initcall(init_mmap_min_addr); 54