xref: /openbmc/linux/security/min_addr.c (revision 32927393)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2788084abSEric Paris #include <linux/init.h>
3788084abSEric Paris #include <linux/mm.h>
4788084abSEric Paris #include <linux/security.h>
5788084abSEric Paris #include <linux/sysctl.h>
6788084abSEric Paris 
7788084abSEric Paris /* amount of vm to protect from userspace access by both DAC and the LSM*/
8788084abSEric Paris unsigned long mmap_min_addr;
9788084abSEric Paris /* amount of vm to protect from userspace using CAP_SYS_RAWIO (DAC) */
10788084abSEric Paris unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
11788084abSEric Paris /* amount of vm to protect from userspace using the LSM = CONFIG_LSM_MMAP_MIN_ADDR */
12788084abSEric Paris 
13788084abSEric Paris /*
14788084abSEric Paris  * Update mmap_min_addr = max(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR)
15788084abSEric Paris  */
update_mmap_min_addr(void)16788084abSEric Paris static void update_mmap_min_addr(void)
17788084abSEric Paris {
18788084abSEric Paris #ifdef CONFIG_LSM_MMAP_MIN_ADDR
19788084abSEric Paris 	if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR)
20788084abSEric Paris 		mmap_min_addr = dac_mmap_min_addr;
21788084abSEric Paris 	else
22788084abSEric Paris 		mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR;
23788084abSEric Paris #else
24788084abSEric Paris 	mmap_min_addr = dac_mmap_min_addr;
25788084abSEric Paris #endif
26788084abSEric Paris }
27788084abSEric Paris 
28788084abSEric Paris /*
29788084abSEric Paris  * sysctl handler which just sets dac_mmap_min_addr = the new value and then
30788084abSEric Paris  * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly
31788084abSEric Paris  */
mmap_min_addr_handler(struct ctl_table * table,int write,void * buffer,size_t * lenp,loff_t * ppos)328d65af78SAlexey Dobriyan int mmap_min_addr_handler(struct ctl_table *table, int write,
3332927393SChristoph Hellwig 			  void *buffer, size_t *lenp, loff_t *ppos)
34788084abSEric Paris {
35788084abSEric Paris 	int ret;
36788084abSEric Paris 
374ae69e6bSKees Cook 	if (write && !capable(CAP_SYS_RAWIO))
380e1a6ef2SKees Cook 		return -EPERM;
390e1a6ef2SKees Cook 
408d65af78SAlexey Dobriyan 	ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
41788084abSEric Paris 
42788084abSEric Paris 	update_mmap_min_addr();
43788084abSEric Paris 
44788084abSEric Paris 	return ret;
45788084abSEric Paris }
46788084abSEric Paris 
init_mmap_min_addr(void)47dd880fbeSH Hartley Sweeten static int __init init_mmap_min_addr(void)
48788084abSEric Paris {
49788084abSEric Paris 	update_mmap_min_addr();
50788084abSEric Paris 
51788084abSEric Paris 	return 0;
52788084abSEric Paris }
53788084abSEric Paris pure_initcall(init_mmap_min_addr);
54