Skip to content

Commit

Permalink
sysctl: Factor out sysctl_data.
Browse files Browse the repository at this point in the history
There as been no easy way to wrap the default sysctl strategy routine except
for returning 0.  Which is not always what we want.  The few instances I have
seen that want different behaviour have written their own version of
sysctl_data.  While not too hard it is unnecessary code and has the potential
for extra bugs.

So to make these situations easier and make that part of sysctl more symetric
I have factord sysctl_data out of do_sysctl_strategy and exported as a
function everyone can use.

Further having sysctl_data be an explicit function makes checking for badly
formed sysctl tables much easier.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Alexey Dobriyan <adobriyan@sw.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
ebiederm authored and Linus Torvalds committed Oct 18, 2007
1 parent d8217f0 commit 49a0c45
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 20 deletions.
1 change: 1 addition & 0 deletions include/linux/sysctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,7 @@ extern int do_sysctl_strategy (struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen);

extern ctl_handler sysctl_data;
extern ctl_handler sysctl_string;
extern ctl_handler sysctl_intvec;
extern ctl_handler sysctl_jiffies;
Expand Down
66 changes: 46 additions & 20 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,6 @@ int do_sysctl_strategy (struct ctl_table *table,
void __user *newval, size_t newlen)
{
int op = 0, rc;
size_t len;

if (oldval)
op |= 004;
Expand All @@ -1464,25 +1463,10 @@ int do_sysctl_strategy (struct ctl_table *table,
/* 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;
}
rc = sysctl_data(table, name, nlen, oldval, oldlenp,
newval, newlen);
if (rc < 0)
return rc;
}
return 0;
}
Expand Down Expand Up @@ -2381,6 +2365,40 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
* General sysctl support routines
*/

/* The generic sysctl data routine (used if no strategy routine supplied) */
int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
size_t len;

/* Get out of I don't have a variable */
if (!table->data || !table->maxlen)
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, table->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(table->data, newval, newlen))
return -EFAULT;
}
return 1;
}

/* The generic string strategy routine: */
int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
Expand Down Expand Up @@ -2569,6 +2587,13 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
return -ENOSYS;
}

int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
return -ENOSYS;
}

int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
Expand Down Expand Up @@ -2616,4 +2641,5 @@ EXPORT_SYMBOL(sysctl_intvec);
EXPORT_SYMBOL(sysctl_jiffies);
EXPORT_SYMBOL(sysctl_ms_jiffies);
EXPORT_SYMBOL(sysctl_string);
EXPORT_SYMBOL(sysctl_data);
EXPORT_SYMBOL(unregister_sysctl_table);

0 comments on commit 49a0c45

Please sign in to comment.