mq_sysctl.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2007 IBM Corporation
  4. *
  5. * Author: Cedric Le Goater <[email protected]>
  6. */
  7. #include <linux/nsproxy.h>
  8. #include <linux/ipc_namespace.h>
  9. #include <linux/sysctl.h>
  10. #include <linux/stat.h>
  11. #include <linux/capability.h>
  12. #include <linux/slab.h>
  13. static int msg_max_limit_min = MIN_MSGMAX;
  14. static int msg_max_limit_max = HARD_MSGMAX;
  15. static int msg_maxsize_limit_min = MIN_MSGSIZEMAX;
  16. static int msg_maxsize_limit_max = HARD_MSGSIZEMAX;
  17. static struct ctl_table mq_sysctls[] = {
  18. {
  19. .procname = "queues_max",
  20. .data = &init_ipc_ns.mq_queues_max,
  21. .maxlen = sizeof(int),
  22. .mode = 0644,
  23. .proc_handler = proc_dointvec,
  24. },
  25. {
  26. .procname = "msg_max",
  27. .data = &init_ipc_ns.mq_msg_max,
  28. .maxlen = sizeof(int),
  29. .mode = 0644,
  30. .proc_handler = proc_dointvec_minmax,
  31. .extra1 = &msg_max_limit_min,
  32. .extra2 = &msg_max_limit_max,
  33. },
  34. {
  35. .procname = "msgsize_max",
  36. .data = &init_ipc_ns.mq_msgsize_max,
  37. .maxlen = sizeof(int),
  38. .mode = 0644,
  39. .proc_handler = proc_dointvec_minmax,
  40. .extra1 = &msg_maxsize_limit_min,
  41. .extra2 = &msg_maxsize_limit_max,
  42. },
  43. {
  44. .procname = "msg_default",
  45. .data = &init_ipc_ns.mq_msg_default,
  46. .maxlen = sizeof(int),
  47. .mode = 0644,
  48. .proc_handler = proc_dointvec_minmax,
  49. .extra1 = &msg_max_limit_min,
  50. .extra2 = &msg_max_limit_max,
  51. },
  52. {
  53. .procname = "msgsize_default",
  54. .data = &init_ipc_ns.mq_msgsize_default,
  55. .maxlen = sizeof(int),
  56. .mode = 0644,
  57. .proc_handler = proc_dointvec_minmax,
  58. .extra1 = &msg_maxsize_limit_min,
  59. .extra2 = &msg_maxsize_limit_max,
  60. },
  61. {}
  62. };
  63. static struct ctl_table_set *set_lookup(struct ctl_table_root *root)
  64. {
  65. return &current->nsproxy->ipc_ns->mq_set;
  66. }
  67. static int set_is_seen(struct ctl_table_set *set)
  68. {
  69. return &current->nsproxy->ipc_ns->mq_set == set;
  70. }
  71. static struct ctl_table_root set_root = {
  72. .lookup = set_lookup,
  73. };
  74. bool setup_mq_sysctls(struct ipc_namespace *ns)
  75. {
  76. struct ctl_table *tbl;
  77. setup_sysctl_set(&ns->mq_set, &set_root, set_is_seen);
  78. tbl = kmemdup(mq_sysctls, sizeof(mq_sysctls), GFP_KERNEL);
  79. if (tbl) {
  80. int i;
  81. for (i = 0; i < ARRAY_SIZE(mq_sysctls); i++) {
  82. if (tbl[i].data == &init_ipc_ns.mq_queues_max)
  83. tbl[i].data = &ns->mq_queues_max;
  84. else if (tbl[i].data == &init_ipc_ns.mq_msg_max)
  85. tbl[i].data = &ns->mq_msg_max;
  86. else if (tbl[i].data == &init_ipc_ns.mq_msgsize_max)
  87. tbl[i].data = &ns->mq_msgsize_max;
  88. else if (tbl[i].data == &init_ipc_ns.mq_msg_default)
  89. tbl[i].data = &ns->mq_msg_default;
  90. else if (tbl[i].data == &init_ipc_ns.mq_msgsize_default)
  91. tbl[i].data = &ns->mq_msgsize_default;
  92. else
  93. tbl[i].data = NULL;
  94. }
  95. ns->mq_sysctls = __register_sysctl_table(&ns->mq_set, "fs/mqueue", tbl);
  96. }
  97. if (!ns->mq_sysctls) {
  98. kfree(tbl);
  99. retire_sysctl_set(&ns->mq_set);
  100. return false;
  101. }
  102. return true;
  103. }
  104. void retire_mq_sysctls(struct ipc_namespace *ns)
  105. {
  106. struct ctl_table *tbl;
  107. tbl = ns->mq_sysctls->ctl_table_arg;
  108. unregister_sysctl_table(ns->mq_sysctls);
  109. retire_sysctl_set(&ns->mq_set);
  110. kfree(tbl);
  111. }