diff options
Diffstat (limited to 'ipc/ipc_sysctl.c')
| -rw-r--r-- | ipc/ipc_sysctl.c | 108 | 
1 files changed, 90 insertions, 18 deletions
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c index 56410faa455..c3f0326e98d 100644 --- a/ipc/ipc_sysctl.c +++ b/ipc/ipc_sysctl.c @@ -18,7 +18,7 @@  #include <linux/msg.h>  #include "util.h" -static void *get_ipc(ctl_table *table) +static void *get_ipc(struct ctl_table *table)  {  	char *which = table->data;  	struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; @@ -27,17 +27,42 @@ static void *get_ipc(ctl_table *table)  }  #ifdef CONFIG_PROC_SYSCTL -static int proc_ipc_dointvec(ctl_table *table, int write, +static int proc_ipc_dointvec(struct ctl_table *table, int write,  	void __user *buffer, size_t *lenp, loff_t *ppos)  {  	struct ctl_table ipc_table; +  	memcpy(&ipc_table, table, sizeof(ipc_table));  	ipc_table.data = get_ipc(table);  	return proc_dointvec(&ipc_table, write, buffer, lenp, ppos);  } -static int proc_ipc_callback_dointvec(ctl_table *table, int write, +static int proc_ipc_dointvec_minmax(struct ctl_table *table, int write, +	void __user *buffer, size_t *lenp, loff_t *ppos) +{ +	struct ctl_table ipc_table; + +	memcpy(&ipc_table, table, sizeof(ipc_table)); +	ipc_table.data = get_ipc(table); + +	return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos); +} + +static int proc_ipc_dointvec_minmax_orphans(struct ctl_table *table, int write, +	void __user *buffer, size_t *lenp, loff_t *ppos) +{ +	struct ipc_namespace *ns = current->nsproxy->ipc_ns; +	int err = proc_ipc_dointvec_minmax(table, write, buffer, lenp, ppos); + +	if (err < 0) +		return err; +	if (ns->shm_rmid_forced) +		shm_destroy_orphaned(ns); +	return err; +} + +static int proc_ipc_callback_dointvec_minmax(struct ctl_table *table, int write,  	void __user *buffer, size_t *lenp, loff_t *ppos)  {  	struct ctl_table ipc_table; @@ -47,7 +72,7 @@ static int proc_ipc_callback_dointvec(ctl_table *table, int write,  	memcpy(&ipc_table, table, sizeof(ipc_table));  	ipc_table.data = get_ipc(table); -	rc = proc_dointvec(&ipc_table, write, buffer, lenp, ppos); +	rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);  	if (write && !rc && lenp_bef == *lenp)  		/* @@ -60,7 +85,7 @@ static int proc_ipc_callback_dointvec(ctl_table *table, int write,  	return rc;  } -static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, +static int proc_ipc_doulongvec_minmax(struct ctl_table *table, int write,  	void __user *buffer, size_t *lenp, loff_t *ppos)  {  	struct ctl_table ipc_table; @@ -94,7 +119,7 @@ static void ipc_auto_callback(int val)  	}  } -static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, +static int proc_ipcauto_dointvec_minmax(struct ctl_table *table, int write,  	void __user *buffer, size_t *lenp, loff_t *ppos)  {  	struct ctl_table ipc_table; @@ -125,60 +150,78 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,  #else  #define proc_ipc_doulongvec_minmax NULL  #define proc_ipc_dointvec	   NULL -#define proc_ipc_callback_dointvec NULL +#define proc_ipc_dointvec_minmax   NULL +#define proc_ipc_dointvec_minmax_orphans   NULL +#define proc_ipc_callback_dointvec_minmax  NULL  #define proc_ipcauto_dointvec_minmax NULL  #endif  static int zero;  static int one = 1; +static int int_max = INT_MAX;  static struct ctl_table ipc_kern_table[] = {  	{  		.procname	= "shmmax",  		.data		= &init_ipc_ns.shm_ctlmax, -		.maxlen		= sizeof (init_ipc_ns.shm_ctlmax), +		.maxlen		= sizeof(init_ipc_ns.shm_ctlmax),  		.mode		= 0644,  		.proc_handler	= proc_ipc_doulongvec_minmax,  	},  	{  		.procname	= "shmall",  		.data		= &init_ipc_ns.shm_ctlall, -		.maxlen		= sizeof (init_ipc_ns.shm_ctlall), +		.maxlen		= sizeof(init_ipc_ns.shm_ctlall),  		.mode		= 0644,  		.proc_handler	= proc_ipc_doulongvec_minmax,  	},  	{  		.procname	= "shmmni",  		.data		= &init_ipc_ns.shm_ctlmni, -		.maxlen		= sizeof (init_ipc_ns.shm_ctlmni), +		.maxlen		= sizeof(init_ipc_ns.shm_ctlmni),  		.mode		= 0644,  		.proc_handler	= proc_ipc_dointvec,  	},  	{ +		.procname	= "shm_rmid_forced", +		.data		= &init_ipc_ns.shm_rmid_forced, +		.maxlen		= sizeof(init_ipc_ns.shm_rmid_forced), +		.mode		= 0644, +		.proc_handler	= proc_ipc_dointvec_minmax_orphans, +		.extra1		= &zero, +		.extra2		= &one, +	}, +	{  		.procname	= "msgmax",  		.data		= &init_ipc_ns.msg_ctlmax, -		.maxlen		= sizeof (init_ipc_ns.msg_ctlmax), +		.maxlen		= sizeof(init_ipc_ns.msg_ctlmax),  		.mode		= 0644, -		.proc_handler	= proc_ipc_dointvec, +		.proc_handler	= proc_ipc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &int_max,  	},  	{  		.procname	= "msgmni",  		.data		= &init_ipc_ns.msg_ctlmni, -		.maxlen		= sizeof (init_ipc_ns.msg_ctlmni), +		.maxlen		= sizeof(init_ipc_ns.msg_ctlmni),  		.mode		= 0644, -		.proc_handler	= proc_ipc_callback_dointvec, +		.proc_handler	= proc_ipc_callback_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &int_max,  	},  	{  		.procname	=  "msgmnb",  		.data		= &init_ipc_ns.msg_ctlmnb, -		.maxlen		= sizeof (init_ipc_ns.msg_ctlmnb), +		.maxlen		= sizeof(init_ipc_ns.msg_ctlmnb),  		.mode		= 0644, -		.proc_handler	= proc_ipc_dointvec, +		.proc_handler	= proc_ipc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &int_max,  	},  	{  		.procname	= "sem",  		.data		= &init_ipc_ns.sem_ctls, -		.maxlen		= 4*sizeof (int), +		.maxlen		= 4*sizeof(int),  		.mode		= 0644,  		.proc_handler	= proc_ipc_dointvec,  	}, @@ -191,6 +234,35 @@ static struct ctl_table ipc_kern_table[] = {  		.extra1		= &zero,  		.extra2		= &one,  	}, +#ifdef CONFIG_CHECKPOINT_RESTORE +	{ +		.procname	= "sem_next_id", +		.data		= &init_ipc_ns.ids[IPC_SEM_IDS].next_id, +		.maxlen		= sizeof(init_ipc_ns.ids[IPC_SEM_IDS].next_id), +		.mode		= 0644, +		.proc_handler	= proc_ipc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &int_max, +	}, +	{ +		.procname	= "msg_next_id", +		.data		= &init_ipc_ns.ids[IPC_MSG_IDS].next_id, +		.maxlen		= sizeof(init_ipc_ns.ids[IPC_MSG_IDS].next_id), +		.mode		= 0644, +		.proc_handler	= proc_ipc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &int_max, +	}, +	{ +		.procname	= "shm_next_id", +		.data		= &init_ipc_ns.ids[IPC_SHM_IDS].next_id, +		.maxlen		= sizeof(init_ipc_ns.ids[IPC_SHM_IDS].next_id), +		.mode		= 0644, +		.proc_handler	= proc_ipc_dointvec_minmax, +		.extra1		= &zero, +		.extra2		= &int_max, +	}, +#endif  	{}  }; @@ -209,4 +281,4 @@ static int __init ipc_sysctl_init(void)  	return 0;  } -__initcall(ipc_sysctl_init); +device_initcall(ipc_sysctl_init);  | 
