4 * Author: Eric Biederman <ebiederm@xmision.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2 of the
12 #include <linux/module.h>
13 #include <linux/ipc.h>
14 #include <linux/nsproxy.h>
15 #include <linux/sysctl.h>
16 #include <linux/uaccess.h>
18 static void *get_ipc(ctl_table
*table
)
20 char *which
= table
->data
;
21 struct ipc_namespace
*ipc_ns
= current
->nsproxy
->ipc_ns
;
22 which
= (which
- (char *)&init_ipc_ns
) + (char *)ipc_ns
;
27 static int proc_ipc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
28 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
30 struct ctl_table ipc_table
;
31 memcpy(&ipc_table
, table
, sizeof(ipc_table
));
32 ipc_table
.data
= get_ipc(table
);
34 return proc_dointvec(&ipc_table
, write
, filp
, buffer
, lenp
, ppos
);
37 static int proc_ipc_doulongvec_minmax(ctl_table
*table
, int write
,
38 struct file
*filp
, void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
40 struct ctl_table ipc_table
;
41 memcpy(&ipc_table
, table
, sizeof(ipc_table
));
42 ipc_table
.data
= get_ipc(table
);
44 return proc_doulongvec_minmax(&ipc_table
, write
, filp
, buffer
,
49 #define proc_ipc_doulongvec_minmax NULL
50 #define proc_ipc_dointvec NULL
53 #ifdef CONFIG_SYSCTL_SYSCALL
54 /* The generic sysctl ipc data routine. */
55 static int sysctl_ipc_data(ctl_table
*table
, int __user
*name
, int nlen
,
56 void __user
*oldval
, size_t __user
*oldlenp
,
57 void __user
*newval
, size_t newlen
)
62 /* Get out of I don't have a variable */
63 if (!table
->data
|| !table
->maxlen
)
66 data
= get_ipc(table
);
70 if (oldval
&& oldlenp
) {
71 if (get_user(len
, oldlenp
))
74 if (len
> table
->maxlen
)
76 if (copy_to_user(oldval
, data
, len
))
78 if (put_user(len
, oldlenp
))
83 if (newval
&& newlen
) {
84 if (newlen
> table
->maxlen
)
85 newlen
= table
->maxlen
;
87 if (copy_from_user(data
, newval
, newlen
))
93 #define sysctl_ipc_data NULL
96 static struct ctl_table ipc_kern_table
[] = {
98 .ctl_name
= KERN_SHMMAX
,
100 .data
= &init_ipc_ns
.shm_ctlmax
,
101 .maxlen
= sizeof (init_ipc_ns
.shm_ctlmax
),
103 .proc_handler
= proc_ipc_doulongvec_minmax
,
104 .strategy
= sysctl_ipc_data
,
107 .ctl_name
= KERN_SHMALL
,
108 .procname
= "shmall",
109 .data
= &init_ipc_ns
.shm_ctlall
,
110 .maxlen
= sizeof (init_ipc_ns
.shm_ctlall
),
112 .proc_handler
= proc_ipc_doulongvec_minmax
,
113 .strategy
= sysctl_ipc_data
,
116 .ctl_name
= KERN_SHMMNI
,
117 .procname
= "shmmni",
118 .data
= &init_ipc_ns
.shm_ctlmni
,
119 .maxlen
= sizeof (init_ipc_ns
.shm_ctlmni
),
121 .proc_handler
= proc_ipc_dointvec
,
122 .strategy
= sysctl_ipc_data
,
125 .ctl_name
= KERN_MSGMAX
,
126 .procname
= "msgmax",
127 .data
= &init_ipc_ns
.msg_ctlmax
,
128 .maxlen
= sizeof (init_ipc_ns
.msg_ctlmax
),
130 .proc_handler
= proc_ipc_dointvec
,
131 .strategy
= sysctl_ipc_data
,
134 .ctl_name
= KERN_MSGMNI
,
135 .procname
= "msgmni",
136 .data
= &init_ipc_ns
.msg_ctlmni
,
137 .maxlen
= sizeof (init_ipc_ns
.msg_ctlmni
),
139 .proc_handler
= proc_ipc_dointvec
,
140 .strategy
= sysctl_ipc_data
,
143 .ctl_name
= KERN_MSGMNB
,
144 .procname
= "msgmnb",
145 .data
= &init_ipc_ns
.msg_ctlmnb
,
146 .maxlen
= sizeof (init_ipc_ns
.msg_ctlmnb
),
148 .proc_handler
= proc_ipc_dointvec
,
149 .strategy
= sysctl_ipc_data
,
152 .ctl_name
= KERN_SEM
,
154 .data
= &init_ipc_ns
.sem_ctls
,
155 .maxlen
= 4*sizeof (int),
157 .proc_handler
= proc_ipc_dointvec
,
158 .strategy
= sysctl_ipc_data
,
163 static struct ctl_table ipc_root_table
[] = {
165 .ctl_name
= CTL_KERN
,
166 .procname
= "kernel",
168 .child
= ipc_kern_table
,
173 static int __init
ipc_sysctl_init(void)
175 register_sysctl_table(ipc_root_table
);
179 __initcall(ipc_sysctl_init
);