Commit 9bc9a6bd authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Linus Torvalds

[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: default avatarEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c4b8b769
......@@ -92,7 +92,9 @@ extern char modprobe_path[];
extern int sg_big_buff;
#endif
#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);
#endif
......@@ -189,6 +191,18 @@ static void put_uts(ctl_table *table, int write, void *which)
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: */
#ifdef CONFIG_PROC_SYSCTL
......@@ -458,58 +472,58 @@ static ctl_table kern_table[] = {
{
.ctl_name = KERN_SHMMAX,
.procname = "shmmax",
.data = NULL,
.maxlen = sizeof (size_t),
.data = &init_ipc_ns.shm_ctlmax,
.maxlen = sizeof (init_ipc_ns.shm_ctlmax),
.mode = 0644,
.proc_handler = &proc_do_ipc_string,
.proc_handler = &proc_ipc_doulongvec_minmax,
},
{
.ctl_name = KERN_SHMALL,
.procname = "shmall",
.data = NULL,
.maxlen = sizeof (size_t),
.data = &init_ipc_ns.shm_ctlall,
.maxlen = sizeof (init_ipc_ns.shm_ctlall),
.mode = 0644,
.proc_handler = &proc_do_ipc_string,
.proc_handler = &proc_ipc_doulongvec_minmax,
},
{
.ctl_name = KERN_SHMMNI,
.procname = "shmmni",
.data = NULL,
.maxlen = sizeof (int),
.data = &init_ipc_ns.shm_ctlmni,
.maxlen = sizeof (init_ipc_ns.shm_ctlmni),
.mode = 0644,
.proc_handler = &proc_do_ipc_string,
.proc_handler = &proc_ipc_dointvec,
},
{
.ctl_name = KERN_MSGMAX,
.procname = "msgmax",
.data = NULL,
.maxlen = sizeof (int),
.data = &init_ipc_ns.msg_ctlmax,
.maxlen = sizeof (init_ipc_ns.msg_ctlmax),
.mode = 0644,
.proc_handler = &proc_do_ipc_string,
.proc_handler = &proc_ipc_dointvec,
},
{
.ctl_name = KERN_MSGMNI,
.procname = "msgmni",
.data = NULL,
.maxlen = sizeof (int),
.data = &init_ipc_ns.msg_ctlmni,
.maxlen = sizeof (init_ipc_ns.msg_ctlmni),
.mode = 0644,
.proc_handler = &proc_do_ipc_string,
.proc_handler = &proc_ipc_dointvec,
},
{
.ctl_name = KERN_MSGMNB,
.procname = "msgmnb",
.data = NULL,
.maxlen = sizeof (int),
.data = &init_ipc_ns.msg_ctlmnb,
.maxlen = sizeof (init_ipc_ns.msg_ctlmnb),
.mode = 0644,
.proc_handler = &proc_do_ipc_string,
.proc_handler = &proc_ipc_dointvec,
},
{
.ctl_name = KERN_SEM,
.procname = "sem",
.data = NULL,
.data = &init_ipc_ns.sem_ctls,
.maxlen = 4*sizeof (int),
.mode = 0644,
.proc_handler = &proc_do_ipc_string,
.proc_handler = &proc_ipc_dointvec,
},
#endif
#ifdef CONFIG_MAGIC_SYSRQ
......@@ -2319,46 +2333,24 @@ int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
}
#ifdef CONFIG_SYSVIPC
static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
void *data;
struct ipc_namespace *ns;
ns = current->nsproxy->ipc_ns;
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,
void *which;
which = get_ipc(table, write);
return __do_proc_dointvec(which, table, write, filp, buffer,
lenp, ppos, NULL, NULL);
proc_minmax:
return __do_proc_doulongvec_minmax(data, table, write, filp, buffer,
}
static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
{
void *which;
which = get_ipc(table, write);
return __do_proc_doulongvec_minmax(which, table, write, filp, buffer,
lenp, ppos, 1l, 1l);
}
#endif
static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment