pid_sysctl.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef LINUX_PID_SYSCTL_H
  3. #define LINUX_PID_SYSCTL_H
  4. #include <linux/pid_namespace.h>
  5. #if defined(CONFIG_SYSCTL) && defined(CONFIG_MEMFD_CREATE)
  6. static int pid_mfd_noexec_dointvec_minmax(const struct ctl_table *table,
  7. int write, void *buf, size_t *lenp, loff_t *ppos)
  8. {
  9. struct pid_namespace *ns = task_active_pid_ns(current);
  10. struct ctl_table table_copy;
  11. int err, scope, parent_scope;
  12. if (write && !ns_capable(ns->user_ns, CAP_SYS_ADMIN))
  13. return -EPERM;
  14. table_copy = *table;
  15. /* You cannot set a lower enforcement value than your parent. */
  16. parent_scope = pidns_memfd_noexec_scope(ns->parent);
  17. /* Equivalent to pidns_memfd_noexec_scope(ns). */
  18. scope = max(READ_ONCE(ns->memfd_noexec_scope), parent_scope);
  19. table_copy.data = &scope;
  20. table_copy.extra1 = &parent_scope;
  21. err = proc_dointvec_minmax(&table_copy, write, buf, lenp, ppos);
  22. if (!err && write)
  23. WRITE_ONCE(ns->memfd_noexec_scope, scope);
  24. return err;
  25. }
  26. static struct ctl_table pid_ns_ctl_table_vm[] = {
  27. {
  28. .procname = "memfd_noexec",
  29. .data = &init_pid_ns.memfd_noexec_scope,
  30. .maxlen = sizeof(init_pid_ns.memfd_noexec_scope),
  31. .mode = 0644,
  32. .proc_handler = pid_mfd_noexec_dointvec_minmax,
  33. .extra1 = SYSCTL_ZERO,
  34. .extra2 = SYSCTL_TWO,
  35. },
  36. };
  37. static inline void register_pid_ns_sysctl_table_vm(void)
  38. {
  39. register_sysctl("vm", pid_ns_ctl_table_vm);
  40. }
  41. #else
  42. static inline void register_pid_ns_sysctl_table_vm(void) {}
  43. #endif
  44. #endif /* LINUX_PID_SYSCTL_H */