xref: /openbmc/linux/ipc/ipc_sysctl.c (revision 0050ee059f7fc86b1df2527aaa14ed5dc72f9973)
1a5494dcdSEric W. Biederman /*
2a5494dcdSEric W. Biederman  *  Copyright (C) 2007
3a5494dcdSEric W. Biederman  *
4a5494dcdSEric W. Biederman  *  Author: Eric Biederman <ebiederm@xmision.com>
5a5494dcdSEric W. Biederman  *
6a5494dcdSEric W. Biederman  *  This program is free software; you can redistribute it and/or
7a5494dcdSEric W. Biederman  *  modify it under the terms of the GNU General Public License as
8a5494dcdSEric W. Biederman  *  published by the Free Software Foundation, version 2 of the
9a5494dcdSEric W. Biederman  *  License.
10a5494dcdSEric W. Biederman  */
11a5494dcdSEric W. Biederman 
12a5494dcdSEric W. Biederman #include <linux/module.h>
13a5494dcdSEric W. Biederman #include <linux/ipc.h>
14a5494dcdSEric W. Biederman #include <linux/nsproxy.h>
15a5494dcdSEric W. Biederman #include <linux/sysctl.h>
16a5494dcdSEric W. Biederman #include <linux/uaccess.h>
17ae5e1b22SPavel Emelyanov #include <linux/ipc_namespace.h>
186546bc42SNadia Derbey #include <linux/msg.h>
196546bc42SNadia Derbey #include "util.h"
20a5494dcdSEric W. Biederman 
21a5c5928bSJoe Perches static void *get_ipc(struct ctl_table *table)
22a5494dcdSEric W. Biederman {
23a5494dcdSEric W. Biederman 	char *which = table->data;
24a5494dcdSEric W. Biederman 	struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
25a5494dcdSEric W. Biederman 	which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
26a5494dcdSEric W. Biederman 	return which;
27a5494dcdSEric W. Biederman }
28a5494dcdSEric W. Biederman 
2911dea190SSerge E. Hallyn #ifdef CONFIG_PROC_SYSCTL
30a5c5928bSJoe Perches static int proc_ipc_dointvec(struct ctl_table *table, int write,
31a5494dcdSEric W. Biederman 	void __user *buffer, size_t *lenp, loff_t *ppos)
32a5494dcdSEric W. Biederman {
33a5494dcdSEric W. Biederman 	struct ctl_table ipc_table;
34b34a6b1dSVasiliy Kulikov 
35a5494dcdSEric W. Biederman 	memcpy(&ipc_table, table, sizeof(ipc_table));
36a5494dcdSEric W. Biederman 	ipc_table.data = get_ipc(table);
37a5494dcdSEric W. Biederman 
388d65af78SAlexey Dobriyan 	return proc_dointvec(&ipc_table, write, buffer, lenp, ppos);
39a5494dcdSEric W. Biederman }
40a5494dcdSEric W. Biederman 
41a5c5928bSJoe Perches static int proc_ipc_dointvec_minmax(struct ctl_table *table, int write,
42b34a6b1dSVasiliy Kulikov 	void __user *buffer, size_t *lenp, loff_t *ppos)
43b34a6b1dSVasiliy Kulikov {
44b34a6b1dSVasiliy Kulikov 	struct ctl_table ipc_table;
45b34a6b1dSVasiliy Kulikov 
46b34a6b1dSVasiliy Kulikov 	memcpy(&ipc_table, table, sizeof(ipc_table));
47b34a6b1dSVasiliy Kulikov 	ipc_table.data = get_ipc(table);
48b34a6b1dSVasiliy Kulikov 
49b34a6b1dSVasiliy Kulikov 	return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
50b34a6b1dSVasiliy Kulikov }
51b34a6b1dSVasiliy Kulikov 
52a5c5928bSJoe Perches static int proc_ipc_dointvec_minmax_orphans(struct ctl_table *table, int write,
53b34a6b1dSVasiliy Kulikov 	void __user *buffer, size_t *lenp, loff_t *ppos)
54b34a6b1dSVasiliy Kulikov {
55b34a6b1dSVasiliy Kulikov 	struct ipc_namespace *ns = current->nsproxy->ipc_ns;
56b34a6b1dSVasiliy Kulikov 	int err = proc_ipc_dointvec_minmax(table, write, buffer, lenp, ppos);
57b34a6b1dSVasiliy Kulikov 
58b34a6b1dSVasiliy Kulikov 	if (err < 0)
59b34a6b1dSVasiliy Kulikov 		return err;
60b34a6b1dSVasiliy Kulikov 	if (ns->shm_rmid_forced)
61b34a6b1dSVasiliy Kulikov 		shm_destroy_orphaned(ns);
62b34a6b1dSVasiliy Kulikov 	return err;
63b34a6b1dSVasiliy Kulikov }
64b34a6b1dSVasiliy Kulikov 
65a5c5928bSJoe Perches static int proc_ipc_doulongvec_minmax(struct ctl_table *table, int write,
668d65af78SAlexey Dobriyan 	void __user *buffer, size_t *lenp, loff_t *ppos)
67a5494dcdSEric W. Biederman {
68a5494dcdSEric W. Biederman 	struct ctl_table ipc_table;
69a5494dcdSEric W. Biederman 	memcpy(&ipc_table, table, sizeof(ipc_table));
70a5494dcdSEric W. Biederman 	ipc_table.data = get_ipc(table);
71a5494dcdSEric W. Biederman 
728d65af78SAlexey Dobriyan 	return proc_doulongvec_minmax(&ipc_table, write, buffer,
73a5494dcdSEric W. Biederman 					lenp, ppos);
74a5494dcdSEric W. Biederman }
75a5494dcdSEric W. Biederman 
76*0050ee05SManfred Spraul static int proc_ipc_auto_msgmni(struct ctl_table *table, int write,
778d65af78SAlexey Dobriyan 	void __user *buffer, size_t *lenp, loff_t *ppos)
789eefe520SNadia Derbey {
799eefe520SNadia Derbey 	struct ctl_table ipc_table;
80*0050ee05SManfred Spraul 	int dummy = 0;
819eefe520SNadia Derbey 
829eefe520SNadia Derbey 	memcpy(&ipc_table, table, sizeof(ipc_table));
83*0050ee05SManfred Spraul 	ipc_table.data = &dummy;
849eefe520SNadia Derbey 
85*0050ee05SManfred Spraul 	if (write)
86*0050ee05SManfred Spraul 		pr_info_once("writing to auto_msgmni has no effect");
879eefe520SNadia Derbey 
88*0050ee05SManfred Spraul 	return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
899eefe520SNadia Derbey }
909eefe520SNadia Derbey 
91a5494dcdSEric W. Biederman #else
92a5494dcdSEric W. Biederman #define proc_ipc_doulongvec_minmax NULL
93a5494dcdSEric W. Biederman #define proc_ipc_dointvec	   NULL
94b34a6b1dSVasiliy Kulikov #define proc_ipc_dointvec_minmax   NULL
95b34a6b1dSVasiliy Kulikov #define proc_ipc_dointvec_minmax_orphans   NULL
96*0050ee05SManfred Spraul #define proc_ipc_auto_msgmni	   NULL
97a5494dcdSEric W. Biederman #endif
98a5494dcdSEric W. Biederman 
999eefe520SNadia Derbey static int zero;
1009eefe520SNadia Derbey static int one = 1;
10103f59566SStanislav Kinsbursky static int int_max = INT_MAX;
1029eefe520SNadia Derbey 
103a5494dcdSEric W. Biederman static struct ctl_table ipc_kern_table[] = {
104a5494dcdSEric W. Biederman 	{
105a5494dcdSEric W. Biederman 		.procname	= "shmmax",
106a5494dcdSEric W. Biederman 		.data		= &init_ipc_ns.shm_ctlmax,
107a5494dcdSEric W. Biederman 		.maxlen		= sizeof(init_ipc_ns.shm_ctlmax),
108a5494dcdSEric W. Biederman 		.mode		= 0644,
109a5494dcdSEric W. Biederman 		.proc_handler	= proc_ipc_doulongvec_minmax,
110a5494dcdSEric W. Biederman 	},
111a5494dcdSEric W. Biederman 	{
112a5494dcdSEric W. Biederman 		.procname	= "shmall",
113a5494dcdSEric W. Biederman 		.data		= &init_ipc_ns.shm_ctlall,
114a5494dcdSEric W. Biederman 		.maxlen		= sizeof(init_ipc_ns.shm_ctlall),
115a5494dcdSEric W. Biederman 		.mode		= 0644,
116a5494dcdSEric W. Biederman 		.proc_handler	= proc_ipc_doulongvec_minmax,
117a5494dcdSEric W. Biederman 	},
118a5494dcdSEric W. Biederman 	{
119a5494dcdSEric W. Biederman 		.procname	= "shmmni",
120a5494dcdSEric W. Biederman 		.data		= &init_ipc_ns.shm_ctlmni,
121a5494dcdSEric W. Biederman 		.maxlen		= sizeof(init_ipc_ns.shm_ctlmni),
122a5494dcdSEric W. Biederman 		.mode		= 0644,
123a5494dcdSEric W. Biederman 		.proc_handler	= proc_ipc_dointvec,
124a5494dcdSEric W. Biederman 	},
125a5494dcdSEric W. Biederman 	{
126b34a6b1dSVasiliy Kulikov 		.procname	= "shm_rmid_forced",
127b34a6b1dSVasiliy Kulikov 		.data		= &init_ipc_ns.shm_rmid_forced,
128b34a6b1dSVasiliy Kulikov 		.maxlen		= sizeof(init_ipc_ns.shm_rmid_forced),
129b34a6b1dSVasiliy Kulikov 		.mode		= 0644,
130b34a6b1dSVasiliy Kulikov 		.proc_handler	= proc_ipc_dointvec_minmax_orphans,
131b34a6b1dSVasiliy Kulikov 		.extra1		= &zero,
132b34a6b1dSVasiliy Kulikov 		.extra2		= &one,
133b34a6b1dSVasiliy Kulikov 	},
134b34a6b1dSVasiliy Kulikov 	{
135a5494dcdSEric W. Biederman 		.procname	= "msgmax",
136a5494dcdSEric W. Biederman 		.data		= &init_ipc_ns.msg_ctlmax,
137a5494dcdSEric W. Biederman 		.maxlen		= sizeof(init_ipc_ns.msg_ctlmax),
138a5494dcdSEric W. Biederman 		.mode		= 0644,
1399bf76ca3SMathias Krause 		.proc_handler	= proc_ipc_dointvec_minmax,
1409bf76ca3SMathias Krause 		.extra1		= &zero,
1419bf76ca3SMathias Krause 		.extra2		= &int_max,
142a5494dcdSEric W. Biederman 	},
143a5494dcdSEric W. Biederman 	{
144a5494dcdSEric W. Biederman 		.procname	= "msgmni",
145a5494dcdSEric W. Biederman 		.data		= &init_ipc_ns.msg_ctlmni,
146a5494dcdSEric W. Biederman 		.maxlen		= sizeof(init_ipc_ns.msg_ctlmni),
147a5494dcdSEric W. Biederman 		.mode		= 0644,
148*0050ee05SManfred Spraul 		.proc_handler	= proc_ipc_dointvec_minmax,
1499bf76ca3SMathias Krause 		.extra1		= &zero,
1509bf76ca3SMathias Krause 		.extra2		= &int_max,
151a5494dcdSEric W. Biederman 	},
152a5494dcdSEric W. Biederman 	{
153*0050ee05SManfred Spraul 		.procname	= "auto_msgmni",
154*0050ee05SManfred Spraul 		.data		= NULL,
155*0050ee05SManfred Spraul 		.maxlen		= sizeof(int),
156*0050ee05SManfred Spraul 		.mode		= 0644,
157*0050ee05SManfred Spraul 		.proc_handler	= proc_ipc_auto_msgmni,
158*0050ee05SManfred Spraul 		.extra1		= &zero,
159*0050ee05SManfred Spraul 		.extra2		= &one,
160*0050ee05SManfred Spraul 	},
161*0050ee05SManfred Spraul 	{
162a5494dcdSEric W. Biederman 		.procname	=  "msgmnb",
163a5494dcdSEric W. Biederman 		.data		= &init_ipc_ns.msg_ctlmnb,
164a5494dcdSEric W. Biederman 		.maxlen		= sizeof(init_ipc_ns.msg_ctlmnb),
165a5494dcdSEric W. Biederman 		.mode		= 0644,
1669bf76ca3SMathias Krause 		.proc_handler	= proc_ipc_dointvec_minmax,
1679bf76ca3SMathias Krause 		.extra1		= &zero,
1689bf76ca3SMathias Krause 		.extra2		= &int_max,
169a5494dcdSEric W. Biederman 	},
170a5494dcdSEric W. Biederman 	{
171a5494dcdSEric W. Biederman 		.procname	= "sem",
172a5494dcdSEric W. Biederman 		.data		= &init_ipc_ns.sem_ctls,
173a5494dcdSEric W. Biederman 		.maxlen		= 4*sizeof(int),
174a5494dcdSEric W. Biederman 		.mode		= 0644,
175a5494dcdSEric W. Biederman 		.proc_handler	= proc_ipc_dointvec,
176a5494dcdSEric W. Biederman 	},
17703f59566SStanislav Kinsbursky #ifdef CONFIG_CHECKPOINT_RESTORE
17803f59566SStanislav Kinsbursky 	{
17903f59566SStanislav Kinsbursky 		.procname	= "sem_next_id",
18003f59566SStanislav Kinsbursky 		.data		= &init_ipc_ns.ids[IPC_SEM_IDS].next_id,
18103f59566SStanislav Kinsbursky 		.maxlen		= sizeof(init_ipc_ns.ids[IPC_SEM_IDS].next_id),
18203f59566SStanislav Kinsbursky 		.mode		= 0644,
18303f59566SStanislav Kinsbursky 		.proc_handler	= proc_ipc_dointvec_minmax,
18403f59566SStanislav Kinsbursky 		.extra1		= &zero,
18503f59566SStanislav Kinsbursky 		.extra2		= &int_max,
18603f59566SStanislav Kinsbursky 	},
18703f59566SStanislav Kinsbursky 	{
18803f59566SStanislav Kinsbursky 		.procname	= "msg_next_id",
18903f59566SStanislav Kinsbursky 		.data		= &init_ipc_ns.ids[IPC_MSG_IDS].next_id,
19003f59566SStanislav Kinsbursky 		.maxlen		= sizeof(init_ipc_ns.ids[IPC_MSG_IDS].next_id),
19103f59566SStanislav Kinsbursky 		.mode		= 0644,
19203f59566SStanislav Kinsbursky 		.proc_handler	= proc_ipc_dointvec_minmax,
19303f59566SStanislav Kinsbursky 		.extra1		= &zero,
19403f59566SStanislav Kinsbursky 		.extra2		= &int_max,
19503f59566SStanislav Kinsbursky 	},
19603f59566SStanislav Kinsbursky 	{
19703f59566SStanislav Kinsbursky 		.procname	= "shm_next_id",
19803f59566SStanislav Kinsbursky 		.data		= &init_ipc_ns.ids[IPC_SHM_IDS].next_id,
19903f59566SStanislav Kinsbursky 		.maxlen		= sizeof(init_ipc_ns.ids[IPC_SHM_IDS].next_id),
20003f59566SStanislav Kinsbursky 		.mode		= 0644,
20103f59566SStanislav Kinsbursky 		.proc_handler	= proc_ipc_dointvec_minmax,
20203f59566SStanislav Kinsbursky 		.extra1		= &zero,
20303f59566SStanislav Kinsbursky 		.extra2		= &int_max,
20403f59566SStanislav Kinsbursky 	},
20503f59566SStanislav Kinsbursky #endif
206a5494dcdSEric W. Biederman 	{}
207a5494dcdSEric W. Biederman };
208a5494dcdSEric W. Biederman 
209a5494dcdSEric W. Biederman static struct ctl_table ipc_root_table[] = {
210a5494dcdSEric W. Biederman 	{
211a5494dcdSEric W. Biederman 		.procname	= "kernel",
212a5494dcdSEric W. Biederman 		.mode		= 0555,
213a5494dcdSEric W. Biederman 		.child		= ipc_kern_table,
214a5494dcdSEric W. Biederman 	},
215a5494dcdSEric W. Biederman 	{}
216a5494dcdSEric W. Biederman };
217a5494dcdSEric W. Biederman 
218a5494dcdSEric W. Biederman static int __init ipc_sysctl_init(void)
219a5494dcdSEric W. Biederman {
2200b4d4147SEric W. Biederman 	register_sysctl_table(ipc_root_table);
221a5494dcdSEric W. Biederman 	return 0;
222a5494dcdSEric W. Biederman }
223a5494dcdSEric W. Biederman 
2246d08a256SDavidlohr Bueso device_initcall(ipc_sysctl_init);
225