Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  Copyright (C) 2007 IBM Corporation
0004  *
0005  *  Author: Cedric Le Goater <clg@fr.ibm.com>
0006  */
0007 
0008 #include <linux/nsproxy.h>
0009 #include <linux/ipc_namespace.h>
0010 #include <linux/sysctl.h>
0011 
0012 #include <linux/stat.h>
0013 #include <linux/capability.h>
0014 #include <linux/slab.h>
0015 
0016 static int msg_max_limit_min = MIN_MSGMAX;
0017 static int msg_max_limit_max = HARD_MSGMAX;
0018 
0019 static int msg_maxsize_limit_min = MIN_MSGSIZEMAX;
0020 static int msg_maxsize_limit_max = HARD_MSGSIZEMAX;
0021 
0022 static struct ctl_table mq_sysctls[] = {
0023     {
0024         .procname   = "queues_max",
0025         .data       = &init_ipc_ns.mq_queues_max,
0026         .maxlen     = sizeof(int),
0027         .mode       = 0644,
0028         .proc_handler   = proc_dointvec,
0029     },
0030     {
0031         .procname   = "msg_max",
0032         .data       = &init_ipc_ns.mq_msg_max,
0033         .maxlen     = sizeof(int),
0034         .mode       = 0644,
0035         .proc_handler   = proc_dointvec_minmax,
0036         .extra1     = &msg_max_limit_min,
0037         .extra2     = &msg_max_limit_max,
0038     },
0039     {
0040         .procname   = "msgsize_max",
0041         .data       = &init_ipc_ns.mq_msgsize_max,
0042         .maxlen     = sizeof(int),
0043         .mode       = 0644,
0044         .proc_handler   = proc_dointvec_minmax,
0045         .extra1     = &msg_maxsize_limit_min,
0046         .extra2     = &msg_maxsize_limit_max,
0047     },
0048     {
0049         .procname   = "msg_default",
0050         .data       = &init_ipc_ns.mq_msg_default,
0051         .maxlen     = sizeof(int),
0052         .mode       = 0644,
0053         .proc_handler   = proc_dointvec_minmax,
0054         .extra1     = &msg_max_limit_min,
0055         .extra2     = &msg_max_limit_max,
0056     },
0057     {
0058         .procname   = "msgsize_default",
0059         .data       = &init_ipc_ns.mq_msgsize_default,
0060         .maxlen     = sizeof(int),
0061         .mode       = 0644,
0062         .proc_handler   = proc_dointvec_minmax,
0063         .extra1     = &msg_maxsize_limit_min,
0064         .extra2     = &msg_maxsize_limit_max,
0065     },
0066     {}
0067 };
0068 
0069 static struct ctl_table_set *set_lookup(struct ctl_table_root *root)
0070 {
0071     return &current->nsproxy->ipc_ns->mq_set;
0072 }
0073 
0074 static int set_is_seen(struct ctl_table_set *set)
0075 {
0076     return &current->nsproxy->ipc_ns->mq_set == set;
0077 }
0078 
0079 static struct ctl_table_root set_root = {
0080     .lookup = set_lookup,
0081 };
0082 
0083 bool setup_mq_sysctls(struct ipc_namespace *ns)
0084 {
0085     struct ctl_table *tbl;
0086 
0087     setup_sysctl_set(&ns->mq_set, &set_root, set_is_seen);
0088 
0089     tbl = kmemdup(mq_sysctls, sizeof(mq_sysctls), GFP_KERNEL);
0090     if (tbl) {
0091         int i;
0092 
0093         for (i = 0; i < ARRAY_SIZE(mq_sysctls); i++) {
0094             if (tbl[i].data == &init_ipc_ns.mq_queues_max)
0095                 tbl[i].data = &ns->mq_queues_max;
0096 
0097             else if (tbl[i].data == &init_ipc_ns.mq_msg_max)
0098                 tbl[i].data = &ns->mq_msg_max;
0099 
0100             else if (tbl[i].data == &init_ipc_ns.mq_msgsize_max)
0101                 tbl[i].data = &ns->mq_msgsize_max;
0102 
0103             else if (tbl[i].data == &init_ipc_ns.mq_msg_default)
0104                 tbl[i].data = &ns->mq_msg_default;
0105 
0106             else if (tbl[i].data == &init_ipc_ns.mq_msgsize_default)
0107                 tbl[i].data = &ns->mq_msgsize_default;
0108             else
0109                 tbl[i].data = NULL;
0110         }
0111 
0112         ns->mq_sysctls = __register_sysctl_table(&ns->mq_set, "fs/mqueue", tbl);
0113     }
0114     if (!ns->mq_sysctls) {
0115         kfree(tbl);
0116         retire_sysctl_set(&ns->mq_set);
0117         return false;
0118     }
0119 
0120     return true;
0121 }
0122 
0123 void retire_mq_sysctls(struct ipc_namespace *ns)
0124 {
0125     struct ctl_table *tbl;
0126 
0127     tbl = ns->mq_sysctls->ctl_table_arg;
0128     unregister_sysctl_table(ns->mq_sysctls);
0129     retire_sysctl_set(&ns->mq_set);
0130     kfree(tbl);
0131 }