diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2006-12-08 02:39:57 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 08:29:03 -0800 |
commit | 6b49a257850fb8ad91f4c76bb712e9213141a34a (patch) | |
tree | 5616780832c9f13c5f21e785052c4583a180490c | |
parent | 9bc9a6bd3cf559bffe962c51efb062e8b5270ca9 (diff) |
[PATCH] sysctl: fix sys_sysctl interface of ipc sysctls
Currently there is a regression and the ipc sysctls don't show up in the
binary sysctl namespace.
This patch adds sysctl_ipc_data to read data/write from the appropriate
namespace and deliver it in the expected manner.
[akpm@osdl.org: warning fix]
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>
-rw-r--r-- | kernel/sysctl.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 10474a63a111..025fcb3c66f8 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -143,6 +143,12 @@ static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen, void **context); +#ifdef CONFIG_SYSVIPC +static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, void **context); +#endif + #ifdef CONFIG_PROC_SYSCTL static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos); @@ -476,6 +482,7 @@ static ctl_table kern_table[] = { .maxlen = sizeof (init_ipc_ns.shm_ctlmax), .mode = 0644, .proc_handler = &proc_ipc_doulongvec_minmax, + .strategy = sysctl_ipc_data, }, { .ctl_name = KERN_SHMALL, @@ -484,6 +491,7 @@ static ctl_table kern_table[] = { .maxlen = sizeof (init_ipc_ns.shm_ctlall), .mode = 0644, .proc_handler = &proc_ipc_doulongvec_minmax, + .strategy = sysctl_ipc_data, }, { .ctl_name = KERN_SHMMNI, @@ -492,6 +500,7 @@ static ctl_table kern_table[] = { .maxlen = sizeof (init_ipc_ns.shm_ctlmni), .mode = 0644, .proc_handler = &proc_ipc_dointvec, + .strategy = sysctl_ipc_data, }, { .ctl_name = KERN_MSGMAX, @@ -500,6 +509,7 @@ static ctl_table kern_table[] = { .maxlen = sizeof (init_ipc_ns.msg_ctlmax), .mode = 0644, .proc_handler = &proc_ipc_dointvec, + .strategy = sysctl_ipc_data, }, { .ctl_name = KERN_MSGMNI, @@ -508,6 +518,7 @@ static ctl_table kern_table[] = { .maxlen = sizeof (init_ipc_ns.msg_ctlmni), .mode = 0644, .proc_handler = &proc_ipc_dointvec, + .strategy = sysctl_ipc_data, }, { .ctl_name = KERN_MSGMNB, @@ -516,6 +527,7 @@ static ctl_table kern_table[] = { .maxlen = sizeof (init_ipc_ns.msg_ctlmnb), .mode = 0644, .proc_handler = &proc_ipc_dointvec, + .strategy = sysctl_ipc_data, }, { .ctl_name = KERN_SEM, @@ -524,6 +536,7 @@ static ctl_table kern_table[] = { .maxlen = 4*sizeof (int), .mode = 0644, .proc_handler = &proc_ipc_dointvec, + .strategy = sysctl_ipc_data, }, #endif #ifdef CONFIG_MAGIC_SYSRQ @@ -2611,6 +2624,47 @@ static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen, return r; } +#ifdef CONFIG_SYSVIPC +/* The generic sysctl ipc data routine. */ +static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, void **context) +{ + size_t len; + void *data; + + /* Get out of I don't have a variable */ + if (!table->data || !table->maxlen) + return -ENOTDIR; + + data = get_ipc(table, 1); + if (!data) + return -ENOTDIR; + + if (oldval && oldlenp) { + if (get_user(len, oldlenp)) + return -EFAULT; + if (len) { + if (len > table->maxlen) + len = table->maxlen; + if (copy_to_user(oldval, data, len)) + return -EFAULT; + if (put_user(len, oldlenp)) + return -EFAULT; + } + } + + if (newval && newlen) { + if (newlen > table->maxlen) + newlen = table->maxlen; + + if (copy_from_user(data, newval, newlen)) + return -EFAULT; + } + return 1; +} +#endif + #else /* CONFIG_SYSCTL_SYSCALL */ @@ -2681,6 +2735,12 @@ static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen, { return -ENOSYS; } +static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, void **context) +{ + return -ENOSYS; +} #endif /* CONFIG_SYSCTL_SYSCALL */ /* |