min_addr.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include <linux/init.h>
  2. #include <linux/mm.h>
  3. #include <linux/security.h>
  4. #include <linux/sysctl.h>
  5. /* amount of vm to protect from userspace access by both DAC and the LSM*/
  6. unsigned long mmap_min_addr;
  7. /* amount of vm to protect from userspace using CAP_SYS_RAWIO (DAC) */
  8. unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
  9. /* amount of vm to protect from userspace using the LSM = CONFIG_LSM_MMAP_MIN_ADDR */
  10. /*
  11. * Update mmap_min_addr = max(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR)
  12. */
  13. static void update_mmap_min_addr(void)
  14. {
  15. #ifdef CONFIG_LSM_MMAP_MIN_ADDR
  16. if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR)
  17. mmap_min_addr = dac_mmap_min_addr;
  18. else
  19. mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR;
  20. #else
  21. mmap_min_addr = dac_mmap_min_addr;
  22. #endif
  23. }
  24. /*
  25. * sysctl handler which just sets dac_mmap_min_addr = the new value and then
  26. * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly
  27. */
  28. int mmap_min_addr_handler(struct ctl_table *table, int write,
  29. void __user *buffer, size_t *lenp, loff_t *ppos)
  30. {
  31. int ret;
  32. if (write && !capable(CAP_SYS_RAWIO))
  33. return -EPERM;
  34. ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
  35. update_mmap_min_addr();
  36. return ret;
  37. }
  38. static int __init init_mmap_min_addr(void)
  39. {
  40. update_mmap_min_addr();
  41. return 0;
  42. }
  43. pure_initcall(init_mmap_min_addr);