--- work-dave/include/linux/sysctl.h | 4 ++ work-dave/kernel/sysctl.c | 55 +++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 24 deletions(-) diff -puN ipc/compat.c~sysv-do-sysctl-strategies0 ipc/compat.c diff -puN ipc/compat_mq.c~sysv-do-sysctl-strategies0 ipc/compat_mq.c diff -puN ipc/mqueue.c~sysv-do-sysctl-strategies0 ipc/mqueue.c diff -puN ipc/msg.c~sysv-do-sysctl-strategies0 ipc/msg.c diff -puN ipc/msgutil.c~sysv-do-sysctl-strategies0 ipc/msgutil.c diff -puN ipc/sem.c~sysv-do-sysctl-strategies0 ipc/sem.c diff -puN ipc/shm.c~sysv-do-sysctl-strategies0 ipc/shm.c diff -puN ipc/util.c~sysv-do-sysctl-strategies0 ipc/util.c diff -puN kernel/sysctl.c~sysv-do-sysctl-strategies0 kernel/sysctl.c --- work/kernel/sysctl.c~sysv-do-sysctl-strategies0 2006-04-18 17:06:49.000000000 -0700 +++ work-dave/kernel/sysctl.c 2006-04-18 17:13:06.000000000 -0700 @@ -1251,6 +1251,35 @@ repeat: return -ENOTDIR; } +int default_sysctl_strategy(ctl_table *table, void *data, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen) +{ + size_t len; + if (data && table->maxlen) { + 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) { + len = newlen; + if (len > table->maxlen) + len = table->maxlen; + if(copy_from_user(data, newval, len)) + return -EFAULT; + } + } + return 0; +} + /* Perform the actual read/write of a sysctl table entry. */ int do_sysctl_strategy (ctl_table *table, int __user *name, int nlen, @@ -1258,7 +1287,6 @@ int do_sysctl_strategy (ctl_table *table void __user *newval, size_t newlen, void **context) { int op = 0, rc; - size_t len; if (oldval) op |= 004; @@ -1275,31 +1303,10 @@ int do_sysctl_strategy (ctl_table *table if (rc > 0) return 0; } - /* If there is no strategy routine, or if the strategy returns * zero, proceed with automatic r/w */ - if (table->data && table->maxlen) { - if (oldval && oldlenp) { - if (get_user(len, oldlenp)) - return -EFAULT; - if (len) { - if (len > table->maxlen) - len = table->maxlen; - if(copy_to_user(oldval, table->data, len)) - return -EFAULT; - if(put_user(len, oldlenp)) - return -EFAULT; - } - } - if (newval && newlen) { - len = newlen; - if (len > table->maxlen) - len = table->maxlen; - if(copy_from_user(table->data, newval, len)) - return -EFAULT; - } - } - return 0; + return default_sysctl_strategy(table, table->data, oldval,oldlenp, + newval, newlen); } /** diff -puN drivers/char/random.c~sysv-do-sysctl-strategies0 drivers/char/random.c diff -puN include/linux/sysctl.h~sysv-do-sysctl-strategies0 include/linux/sysctl.h --- work/include/linux/sysctl.h~sysv-do-sysctl-strategies0 2006-04-18 17:13:37.000000000 -0700 +++ work-dave/include/linux/sysctl.h 2006-04-18 17:14:40.000000000 -0700 @@ -945,6 +945,10 @@ extern int do_sysctl_strategy (ctl_table void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen, void ** context); +extern int default_sysctl_strategy(ctl_table *table, void *data, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen); + extern ctl_handler sysctl_string; extern ctl_handler sysctl_intvec; extern ctl_handler sysctl_jiffies; _