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>
17 #include <linux/ipc_namespace.h>
19 static void *get_ipc(ctl_table
*table
)
21 char *which
= table
->data
;
22 struct ipc_namespace
*ipc_ns
= current
->nsproxy
->ipc_ns
;
23 which
= (which
- (char *)&init_ipc_ns
) + (char *)ipc_ns
;
28 static int proc_ipc_dointvec(ctl_table
*table
, int write
, struct file
*filp
,
29 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
31 struct ctl_table ipc_table
;
32 memcpy(&ipc_table
, table
, sizeof(ipc_table
));
33 ipc_table
.data
= get_ipc(table
);
35 return proc_dointvec(&ipc_table
, write
, filp
, buffer
, lenp
, ppos
);
38 static int proc_ipc_doulongvec_minmax(ctl_table
*table
, int write
,
39 struct file
*filp
, void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
41 struct ctl_table ipc_table
;
42 memcpy(&ipc_table
, table
, sizeof(ipc_table
));
43 ipc_table
.data
= get_ipc(table
);
45 return proc_doulongvec_minmax(&ipc_table
, write
, filp
, buffer
,
50 #define proc_ipc_doulongvec_minmax NULL
51 #define proc_ipc_dointvec NULL
54 #ifdef CONFIG_SYSCTL_SYSCALL
55 /* The generic sysctl ipc data routine. */
56 static int sysctl_ipc_data(ctl_table
*table
, int __user
*name
, int nlen
,
57 void __user
*oldval
, size_t __user
*oldlenp
,
58 void __user
*newval
, size_t newlen
)
63 /* Get out of I don't have a variable */
64 if (!table
->data
|| !table
->maxlen
)
67 data
= get_ipc(table
);
71 if (oldval
&& oldlenp
) {
72 if (get_user(len
, oldlenp
))
75 if (len
> table
->maxlen
)
77 if (copy_to_user(oldval
, data
, len
))
79 if (put_user(len
, oldlenp
))
84 if (newval
&& newlen
) {
85 if (newlen
> table
->maxlen
)
86 newlen
= table
->maxlen
;
88 if (copy_from_user(data
, newval
, newlen
))
94 #define sysctl_ipc_data NULL
97 static struct ctl_table ipc_kern_table
[] = {
99 .ctl_name
= KERN_SHMMAX
,
100 .procname
= "shmmax",
101 .data
= &init_ipc_ns
.shm_ctlmax
,
102 .maxlen
= sizeof (init_ipc_ns
.shm_ctlmax
),
104 .proc_handler
= proc_ipc_doulongvec_minmax
,
105 .strategy
= sysctl_ipc_data
,
108 .ctl_name
= KERN_SHMALL
,
109 .procname
= "shmall",
110 .data
= &init_ipc_ns
.shm_ctlall
,
111 .maxlen
= sizeof (init_ipc_ns
.shm_ctlall
),
113 .proc_handler
= proc_ipc_doulongvec_minmax
,
114 .strategy
= sysctl_ipc_data
,
117 .ctl_name
= KERN_SHMMNI
,
118 .procname
= "shmmni",
119 .data
= &init_ipc_ns
.shm_ctlmni
,
120 .maxlen
= sizeof (init_ipc_ns
.shm_ctlmni
),
122 .proc_handler
= proc_ipc_dointvec
,
123 .strategy
= sysctl_ipc_data
,
126 .ctl_name
= KERN_MSGMAX
,
127 .procname
= "msgmax",
128 .data
= &init_ipc_ns
.msg_ctlmax
,
129 .maxlen
= sizeof (init_ipc_ns
.msg_ctlmax
),
131 .proc_handler
= proc_ipc_dointvec
,
132 .strategy
= sysctl_ipc_data
,
135 .ctl_name
= KERN_MSGMNI
,
136 .procname
= "msgmni",
137 .data
= &init_ipc_ns
.msg_ctlmni
,
138 .maxlen
= sizeof (init_ipc_ns
.msg_ctlmni
),
140 .proc_handler
= proc_ipc_dointvec
,
141 .strategy
= sysctl_ipc_data
,
144 .ctl_name
= KERN_MSGMNB
,
145 .procname
= "msgmnb",
146 .data
= &init_ipc_ns
.msg_ctlmnb
,
147 .maxlen
= sizeof (init_ipc_ns
.msg_ctlmnb
),
149 .proc_handler
= proc_ipc_dointvec
,
150 .strategy
= sysctl_ipc_data
,
153 .ctl_name
= KERN_SEM
,
155 .data
= &init_ipc_ns
.sem_ctls
,
156 .maxlen
= 4*sizeof (int),
158 .proc_handler
= proc_ipc_dointvec
,
159 .strategy
= sysctl_ipc_data
,
164 static struct ctl_table ipc_root_table
[] = {
166 .ctl_name
= CTL_KERN
,
167 .procname
= "kernel",
169 .child
= ipc_kern_table
,
174 static int __init
ipc_sysctl_init(void)
176 register_sysctl_table(ipc_root_table
);
180 __initcall(ipc_sysctl_init
);