[PATCH] sysctl: simplify ipc ns specific sysctls
Refactor the ipc sysctl support so that it is simpler, more readable, and prepares for fixing the bug with the wrong values being returned in the sys_sysctl interface. The function proc_do_ipc_string() was misnamed as it never handled strings. It's magic of when to work with strings and when to work with longs belonged in the sysctl table. I couldn't tell if the code would work if you disabled the ipc namespace but it certainly looked like it would have problems. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
c4b8b769fa
commit
9bc9a6bd3c
1 changed files with 49 additions and 57 deletions
102
kernel/sysctl.c
102
kernel/sysctl.c
|
@ -92,7 +92,9 @@ extern char modprobe_path[];
|
||||||
extern int sg_big_buff;
|
extern int sg_big_buff;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SYSVIPC
|
#ifdef CONFIG_SYSVIPC
|
||||||
static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
|
static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
|
||||||
|
void __user *buffer, size_t *lenp, loff_t *ppos);
|
||||||
|
static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos);
|
void __user *buffer, size_t *lenp, loff_t *ppos);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -189,6 +191,18 @@ static void put_uts(ctl_table *table, int write, void *which)
|
||||||
up_write(&uts_sem);
|
up_write(&uts_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYSVIPC
|
||||||
|
static void *get_ipc(ctl_table *table, int write)
|
||||||
|
{
|
||||||
|
char *which = table->data;
|
||||||
|
struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
|
||||||
|
which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
|
||||||
|
return which;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define get_ipc(T,W) ((T)->data)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* /proc declarations: */
|
/* /proc declarations: */
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_SYSCTL
|
#ifdef CONFIG_PROC_SYSCTL
|
||||||
|
@ -458,58 +472,58 @@ static ctl_table kern_table[] = {
|
||||||
{
|
{
|
||||||
.ctl_name = KERN_SHMMAX,
|
.ctl_name = KERN_SHMMAX,
|
||||||
.procname = "shmmax",
|
.procname = "shmmax",
|
||||||
.data = NULL,
|
.data = &init_ipc_ns.shm_ctlmax,
|
||||||
.maxlen = sizeof (size_t),
|
.maxlen = sizeof (init_ipc_ns.shm_ctlmax),
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_do_ipc_string,
|
.proc_handler = &proc_ipc_doulongvec_minmax,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.ctl_name = KERN_SHMALL,
|
.ctl_name = KERN_SHMALL,
|
||||||
.procname = "shmall",
|
.procname = "shmall",
|
||||||
.data = NULL,
|
.data = &init_ipc_ns.shm_ctlall,
|
||||||
.maxlen = sizeof (size_t),
|
.maxlen = sizeof (init_ipc_ns.shm_ctlall),
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_do_ipc_string,
|
.proc_handler = &proc_ipc_doulongvec_minmax,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.ctl_name = KERN_SHMMNI,
|
.ctl_name = KERN_SHMMNI,
|
||||||
.procname = "shmmni",
|
.procname = "shmmni",
|
||||||
.data = NULL,
|
.data = &init_ipc_ns.shm_ctlmni,
|
||||||
.maxlen = sizeof (int),
|
.maxlen = sizeof (init_ipc_ns.shm_ctlmni),
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_do_ipc_string,
|
.proc_handler = &proc_ipc_dointvec,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.ctl_name = KERN_MSGMAX,
|
.ctl_name = KERN_MSGMAX,
|
||||||
.procname = "msgmax",
|
.procname = "msgmax",
|
||||||
.data = NULL,
|
.data = &init_ipc_ns.msg_ctlmax,
|
||||||
.maxlen = sizeof (int),
|
.maxlen = sizeof (init_ipc_ns.msg_ctlmax),
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_do_ipc_string,
|
.proc_handler = &proc_ipc_dointvec,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.ctl_name = KERN_MSGMNI,
|
.ctl_name = KERN_MSGMNI,
|
||||||
.procname = "msgmni",
|
.procname = "msgmni",
|
||||||
.data = NULL,
|
.data = &init_ipc_ns.msg_ctlmni,
|
||||||
.maxlen = sizeof (int),
|
.maxlen = sizeof (init_ipc_ns.msg_ctlmni),
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_do_ipc_string,
|
.proc_handler = &proc_ipc_dointvec,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.ctl_name = KERN_MSGMNB,
|
.ctl_name = KERN_MSGMNB,
|
||||||
.procname = "msgmnb",
|
.procname = "msgmnb",
|
||||||
.data = NULL,
|
.data = &init_ipc_ns.msg_ctlmnb,
|
||||||
.maxlen = sizeof (int),
|
.maxlen = sizeof (init_ipc_ns.msg_ctlmnb),
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_do_ipc_string,
|
.proc_handler = &proc_ipc_dointvec,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.ctl_name = KERN_SEM,
|
.ctl_name = KERN_SEM,
|
||||||
.procname = "sem",
|
.procname = "sem",
|
||||||
.data = NULL,
|
.data = &init_ipc_ns.sem_ctls,
|
||||||
.maxlen = 4*sizeof (int),
|
.maxlen = 4*sizeof (int),
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = &proc_do_ipc_string,
|
.proc_handler = &proc_ipc_dointvec,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_MAGIC_SYSRQ
|
#ifdef CONFIG_MAGIC_SYSRQ
|
||||||
|
@ -2319,46 +2333,24 @@ int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SYSVIPC
|
#ifdef CONFIG_SYSVIPC
|
||||||
static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
|
static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
|
||||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||||
{
|
{
|
||||||
void *data;
|
void *which;
|
||||||
struct ipc_namespace *ns;
|
which = get_ipc(table, write);
|
||||||
|
return __do_proc_dointvec(which, table, write, filp, buffer,
|
||||||
ns = current->nsproxy->ipc_ns;
|
lenp, ppos, NULL, NULL);
|
||||||
|
|
||||||
switch (table->ctl_name) {
|
|
||||||
case KERN_SHMMAX:
|
|
||||||
data = &ns->shm_ctlmax;
|
|
||||||
goto proc_minmax;
|
|
||||||
case KERN_SHMALL:
|
|
||||||
data = &ns->shm_ctlall;
|
|
||||||
goto proc_minmax;
|
|
||||||
case KERN_SHMMNI:
|
|
||||||
data = &ns->shm_ctlmni;
|
|
||||||
break;
|
|
||||||
case KERN_MSGMAX:
|
|
||||||
data = &ns->msg_ctlmax;
|
|
||||||
break;
|
|
||||||
case KERN_MSGMNI:
|
|
||||||
data = &ns->msg_ctlmni;
|
|
||||||
break;
|
|
||||||
case KERN_MSGMNB:
|
|
||||||
data = &ns->msg_ctlmnb;
|
|
||||||
break;
|
|
||||||
case KERN_SEM:
|
|
||||||
data = &ns->sem_ctls;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return __do_proc_dointvec(data, table, write, filp, buffer,
|
static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
|
||||||
lenp, ppos, NULL, NULL);
|
struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||||
proc_minmax:
|
{
|
||||||
return __do_proc_doulongvec_minmax(data, table, write, filp, buffer,
|
void *which;
|
||||||
|
which = get_ipc(table, write);
|
||||||
|
return __do_proc_doulongvec_minmax(which, table, write, filp, buffer,
|
||||||
lenp, ppos, 1l, 1l);
|
lenp, ppos, 1l, 1l);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
|
static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
|
||||||
|
|
Loading…
Reference in a new issue