aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--init/Kconfig6
-rw-r--r--ipc/Makefile1
-rw-r--r--ipc/ipc_sysctl.c183
-rw-r--r--kernel/sysctl.c176
4 files changed, 190 insertions, 176 deletions
diff --git a/init/Kconfig b/init/Kconfig
index ad33c979e0b3..f977086e118a 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -125,6 +125,12 @@ config IPC_NS
125 environments, to use ipc namespaces to provide different ipc 125 environments, to use ipc namespaces to provide different ipc
126 objects for different servers. If unsure, say N. 126 objects for different servers. If unsure, say N.
127 127
128config SYSVIPC_SYSCTL
129 bool
130 depends on SYSVIPC
131 depends on SYSCTL
132 default y
133
128config POSIX_MQUEUE 134config POSIX_MQUEUE
129 bool "POSIX Message Queues" 135 bool "POSIX Message Queues"
130 depends on NET && EXPERIMENTAL 136 depends on NET && EXPERIMENTAL
diff --git a/ipc/Makefile b/ipc/Makefile
index 0a6d626cd794..b93bba6652f1 100644
--- a/ipc/Makefile
+++ b/ipc/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o 5obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
6obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o 6obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o
7obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
7obj_mq-$(CONFIG_COMPAT) += compat_mq.o 8obj_mq-$(CONFIG_COMPAT) += compat_mq.o
8obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) 9obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
9 10
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
new file mode 100644
index 000000000000..2c17d83b9093
--- /dev/null
+++ b/ipc/ipc_sysctl.c
@@ -0,0 +1,183 @@
1/*
2 * Copyright (C) 2007
3 *
4 * Author: Eric Biederman <ebiederm@xmision.com>
5 *
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
9 * License.
10 */
11
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
18#ifdef CONFIG_IPC_NS
19static void *get_ipc(ctl_table *table)
20{
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;
24 return which;
25}
26#else
27#define get_ipc(T) ((T)->data)
28#endif
29
30#ifdef CONFIG_PROC_FS
31static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
32 void __user *buffer, size_t *lenp, loff_t *ppos)
33{
34 struct ctl_table ipc_table;
35 memcpy(&ipc_table, table, sizeof(ipc_table));
36 ipc_table.data = get_ipc(table);
37
38 return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos);
39}
40
41static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
42 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
43{
44 struct ctl_table ipc_table;
45 memcpy(&ipc_table, table, sizeof(ipc_table));
46 ipc_table.data = get_ipc(table);
47
48 return proc_doulongvec_minmax(&ipc_table, write, filp, buffer,
49 lenp, ppos);
50}
51
52#else
53#define proc_ipc_doulongvec_minmax NULL
54#define proc_ipc_dointvec NULL
55#endif
56
57#ifdef CONFIG_SYSCTL_SYSCALL
58/* The generic sysctl ipc data routine. */
59static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
60 void __user *oldval, size_t __user *oldlenp,
61 void __user *newval, size_t newlen)
62{
63 size_t len;
64 void *data;
65
66 /* Get out of I don't have a variable */
67 if (!table->data || !table->maxlen)
68 return -ENOTDIR;
69
70 data = get_ipc(table);
71 if (!data)
72 return -ENOTDIR;
73
74 if (oldval && oldlenp) {
75 if (get_user(len, oldlenp))
76 return -EFAULT;
77 if (len) {
78 if (len > table->maxlen)
79 len = table->maxlen;
80 if (copy_to_user(oldval, data, len))
81 return -EFAULT;
82 if (put_user(len, oldlenp))
83 return -EFAULT;
84 }
85 }
86
87 if (newval && newlen) {
88 if (newlen > table->maxlen)
89 newlen = table->maxlen;
90
91 if (copy_from_user(data, newval, newlen))
92 return -EFAULT;
93 }
94 return 1;
95}
96#else
97#define sysctl_ipc_data NULL
98#endif
99
100static struct ctl_table ipc_kern_table[] = {
101 {
102 .ctl_name = KERN_SHMMAX,
103 .procname = "shmmax",
104 .data = &init_ipc_ns.shm_ctlmax,
105 .maxlen = sizeof (init_ipc_ns.shm_ctlmax),
106 .mode = 0644,
107 .proc_handler = proc_ipc_doulongvec_minmax,
108 .strategy = sysctl_ipc_data,
109 },
110 {
111 .ctl_name = KERN_SHMALL,
112 .procname = "shmall",
113 .data = &init_ipc_ns.shm_ctlall,
114 .maxlen = sizeof (init_ipc_ns.shm_ctlall),
115 .mode = 0644,
116 .proc_handler = proc_ipc_doulongvec_minmax,
117 .strategy = sysctl_ipc_data,
118 },
119 {
120 .ctl_name = KERN_SHMMNI,
121 .procname = "shmmni",
122 .data = &init_ipc_ns.shm_ctlmni,
123 .maxlen = sizeof (init_ipc_ns.shm_ctlmni),
124 .mode = 0644,
125 .proc_handler = proc_ipc_dointvec,
126 .strategy = sysctl_ipc_data,
127 },
128 {
129 .ctl_name = KERN_MSGMAX,
130 .procname = "msgmax",
131 .data = &init_ipc_ns.msg_ctlmax,
132 .maxlen = sizeof (init_ipc_ns.msg_ctlmax),
133 .mode = 0644,
134 .proc_handler = proc_ipc_dointvec,
135 .strategy = sysctl_ipc_data,
136 },
137 {
138 .ctl_name = KERN_MSGMNI,
139 .procname = "msgmni",
140 .data = &init_ipc_ns.msg_ctlmni,
141 .maxlen = sizeof (init_ipc_ns.msg_ctlmni),
142 .mode = 0644,
143 .proc_handler = proc_ipc_dointvec,
144 .strategy = sysctl_ipc_data,
145 },
146 {
147 .ctl_name = KERN_MSGMNB,
148 .procname = "msgmnb",
149 .data = &init_ipc_ns.msg_ctlmnb,
150 .maxlen = sizeof (init_ipc_ns.msg_ctlmnb),
151 .mode = 0644,
152 .proc_handler = proc_ipc_dointvec,
153 .strategy = sysctl_ipc_data,
154 },
155 {
156 .ctl_name = KERN_SEM,
157 .procname = "sem",
158 .data = &init_ipc_ns.sem_ctls,
159 .maxlen = 4*sizeof (int),
160 .mode = 0644,
161 .proc_handler = proc_ipc_dointvec,
162 .strategy = sysctl_ipc_data,
163 },
164 {}
165};
166
167static struct ctl_table ipc_root_table[] = {
168 {
169 .ctl_name = CTL_KERN,
170 .procname = "kernel",
171 .mode = 0555,
172 .child = ipc_kern_table,
173 },
174 {}
175};
176
177static int __init ipc_sysctl_init(void)
178{
179 register_sysctl_table(ipc_root_table, 0);
180 return 0;
181}
182
183__initcall(ipc_sysctl_init);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index eff1d36c0687..ca376e733ce4 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -90,12 +90,6 @@ extern char modprobe_path[];
90#ifdef CONFIG_CHR_DEV_SG 90#ifdef CONFIG_CHR_DEV_SG
91extern int sg_big_buff; 91extern int sg_big_buff;
92#endif 92#endif
93#ifdef CONFIG_SYSVIPC
94static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
95 void __user *buffer, size_t *lenp, loff_t *ppos);
96static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
97 void __user *buffer, size_t *lenp, loff_t *ppos);
98#endif
99 93
100#ifdef __sparc__ 94#ifdef __sparc__
101extern char reboot_command []; 95extern char reboot_command [];
@@ -135,11 +129,6 @@ static int parse_table(int __user *, int, void __user *, size_t __user *,
135 void __user *, size_t, ctl_table *); 129 void __user *, size_t, ctl_table *);
136#endif 130#endif
137 131
138#ifdef CONFIG_SYSVIPC
139static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
140 void __user *oldval, size_t __user *oldlenp,
141 void __user *newval, size_t newlen);
142#endif
143 132
144#ifdef CONFIG_PROC_SYSCTL 133#ifdef CONFIG_PROC_SYSCTL
145static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, 134static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
@@ -169,17 +158,6 @@ extern ctl_table inotify_table[];
169int sysctl_legacy_va_layout; 158int sysctl_legacy_va_layout;
170#endif 159#endif
171 160
172#ifdef CONFIG_SYSVIPC
173static void *get_ipc(ctl_table *table, int write)
174{
175 char *which = table->data;
176 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
177 which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
178 return which;
179}
180#else
181#define get_ipc(T,W) ((T)->data)
182#endif
183 161
184/* /proc declarations: */ 162/* /proc declarations: */
185 163
@@ -403,71 +381,6 @@ static ctl_table kern_table[] = {
403 .proc_handler = &proc_dointvec, 381 .proc_handler = &proc_dointvec,
404 }, 382 },
405#endif 383#endif
406#ifdef CONFIG_SYSVIPC
407 {
408 .ctl_name = KERN_SHMMAX,
409 .procname = "shmmax",
410 .data = &init_ipc_ns.shm_ctlmax,
411 .maxlen = sizeof (init_ipc_ns.shm_ctlmax),
412 .mode = 0644,
413 .proc_handler = &proc_ipc_doulongvec_minmax,
414 .strategy = sysctl_ipc_data,
415 },
416 {
417 .ctl_name = KERN_SHMALL,
418 .procname = "shmall",
419 .data = &init_ipc_ns.shm_ctlall,
420 .maxlen = sizeof (init_ipc_ns.shm_ctlall),
421 .mode = 0644,
422 .proc_handler = &proc_ipc_doulongvec_minmax,
423 .strategy = sysctl_ipc_data,
424 },
425 {
426 .ctl_name = KERN_SHMMNI,
427 .procname = "shmmni",
428 .data = &init_ipc_ns.shm_ctlmni,
429 .maxlen = sizeof (init_ipc_ns.shm_ctlmni),
430 .mode = 0644,
431 .proc_handler = &proc_ipc_dointvec,
432 .strategy = sysctl_ipc_data,
433 },
434 {
435 .ctl_name = KERN_MSGMAX,
436 .procname = "msgmax",
437 .data = &init_ipc_ns.msg_ctlmax,
438 .maxlen = sizeof (init_ipc_ns.msg_ctlmax),
439 .mode = 0644,
440 .proc_handler = &proc_ipc_dointvec,
441 .strategy = sysctl_ipc_data,
442 },
443 {
444 .ctl_name = KERN_MSGMNI,
445 .procname = "msgmni",
446 .data = &init_ipc_ns.msg_ctlmni,
447 .maxlen = sizeof (init_ipc_ns.msg_ctlmni),
448 .mode = 0644,
449 .proc_handler = &proc_ipc_dointvec,
450 .strategy = sysctl_ipc_data,
451 },
452 {
453 .ctl_name = KERN_MSGMNB,
454 .procname = "msgmnb",
455 .data = &init_ipc_ns.msg_ctlmnb,
456 .maxlen = sizeof (init_ipc_ns.msg_ctlmnb),
457 .mode = 0644,
458 .proc_handler = &proc_ipc_dointvec,
459 .strategy = sysctl_ipc_data,
460 },
461 {
462 .ctl_name = KERN_SEM,
463 .procname = "sem",
464 .data = &init_ipc_ns.sem_ctls,
465 .maxlen = 4*sizeof (int),
466 .mode = 0644,
467 .proc_handler = &proc_ipc_dointvec,
468 .strategy = sysctl_ipc_data,
469 },
470#endif
471#ifdef CONFIG_MAGIC_SYSRQ 384#ifdef CONFIG_MAGIC_SYSRQ
472 { 385 {
473 .ctl_name = KERN_SYSRQ, 386 .ctl_name = KERN_SYSRQ,
@@ -2269,27 +2182,6 @@ int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
2269 do_proc_dointvec_ms_jiffies_conv, NULL); 2182 do_proc_dointvec_ms_jiffies_conv, NULL);
2270} 2183}
2271 2184
2272#ifdef CONFIG_SYSVIPC
2273static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
2274 void __user *buffer, size_t *lenp, loff_t *ppos)
2275{
2276 void *which;
2277 which = get_ipc(table, write);
2278 return __do_proc_dointvec(which, table, write, filp, buffer,
2279 lenp, ppos, NULL, NULL);
2280}
2281
2282static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
2283 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
2284{
2285 void *which;
2286 which = get_ipc(table, write);
2287 return __do_proc_doulongvec_minmax(which, table, write, filp, buffer,
2288 lenp, ppos, 1l, 1l);
2289}
2290
2291#endif
2292
2293static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, 2185static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
2294 void __user *buffer, size_t *lenp, loff_t *ppos) 2186 void __user *buffer, size_t *lenp, loff_t *ppos)
2295{ 2187{
@@ -2320,25 +2212,6 @@ int proc_dostring(ctl_table *table, int write, struct file *filp,
2320 return -ENOSYS; 2212 return -ENOSYS;
2321} 2213}
2322 2214
2323#ifdef CONFIG_SYSVIPC
2324static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
2325 void __user *buffer, size_t *lenp, loff_t *ppos)
2326{
2327 return -ENOSYS;
2328}
2329static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
2330 void __user *buffer, size_t *lenp, loff_t *ppos)
2331{
2332 return -ENOSYS;
2333}
2334static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
2335 struct file *filp, void __user *buffer,
2336 size_t *lenp, loff_t *ppos)
2337{
2338 return -ENOSYS;
2339}
2340#endif
2341
2342int proc_dointvec(ctl_table *table, int write, struct file *filp, 2215int proc_dointvec(ctl_table *table, int write, struct file *filp,
2343 void __user *buffer, size_t *lenp, loff_t *ppos) 2216 void __user *buffer, size_t *lenp, loff_t *ppos)
2344{ 2217{
@@ -2550,47 +2423,6 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
2550 2423
2551 2424
2552 2425
2553#ifdef CONFIG_SYSVIPC
2554/* The generic sysctl ipc data routine. */
2555static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
2556 void __user *oldval, size_t __user *oldlenp,
2557 void __user *newval, size_t newlen)
2558{
2559 size_t len;
2560 void *data;
2561
2562 /* Get out of I don't have a variable */
2563 if (!table->data || !table->maxlen)
2564 return -ENOTDIR;
2565
2566 data = get_ipc(table, 1);
2567 if (!data)
2568 return -ENOTDIR;
2569
2570 if (oldval && oldlenp) {
2571 if (get_user(len, oldlenp))
2572 return -EFAULT;
2573 if (len) {
2574 if (len > table->maxlen)
2575 len = table->maxlen;
2576 if (copy_to_user(oldval, data, len))
2577 return -EFAULT;
2578 if (put_user(len, oldlenp))
2579 return -EFAULT;
2580 }
2581 }
2582
2583 if (newval && newlen) {
2584 if (newlen > table->maxlen)
2585 newlen = table->maxlen;
2586
2587 if (copy_from_user(data, newval, newlen))
2588 return -EFAULT;
2589 }
2590 return 1;
2591}
2592#endif
2593
2594#else /* CONFIG_SYSCTL_SYSCALL */ 2426#else /* CONFIG_SYSCTL_SYSCALL */
2595 2427
2596 2428
@@ -2655,14 +2487,6 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
2655 return -ENOSYS; 2487 return -ENOSYS;
2656} 2488}
2657 2489
2658#ifdef CONFIG_SYSVIPC
2659static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
2660 void __user *oldval, size_t __user *oldlenp,
2661 void __user *newval, size_t newlen)
2662{
2663 return -ENOSYS;
2664}
2665#endif
2666#endif /* CONFIG_SYSCTL_SYSCALL */ 2490#endif /* CONFIG_SYSCTL_SYSCALL */
2667 2491
2668/* 2492/*