[lkml]   [2005]   [Dec]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH] Fix user data corrupted by old value return of sysctl
If the user reads a sysctl entry which is of string type
by sysctl syscall, this call probably corrupts the user data
right after the old value buffer, the issue lies in sysctl_string
seting 0 to oldval[len], len is the available buffer size
specified by the user, obviously, this will write to the first
byte of the user memory place immediate after the old value buffer
, the correct way is that sysctl_string doesn't set 0, the user
should do it by self in the program.

The following program verifies this point:

#include <linux/unistd.h>
#include <linux/types.h>
#include <linux/sysctl.h>
#include <errno.h>

_syscall1(int, _sysctl, struct __sysctl_args *, args);
int sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
void *newval, size_t newlen)
struct __sysctl_args args
= {name,nlen,oldval,oldlenp,newval,newlen};

return _sysctl(&args);

#define SIZE(x) sizeof(x)/sizeof(x[0])
#define OSNAMESZ 4

struct mystruct {
char osname[OSNAMESZ];
int target;
int osnamelth;
} myos;

int name[] = { CTL_KERN, KERN_NODENAME };

int main(int argc, char * argv[])
{ = 1;
printf("target = %d\n",;
myos.osnamelth = SIZE(myos.osname);
if (sysctl(name, SIZE(name), myos.osname,
&myos.osnamelth, 0, 0))
else {
printf("Current host name: %s\n", myos.osname);
printf("target = %d\n",;
return 0;

Copy it to file sysctl-safe.c, then
$ hostname
$ gcc sysctl-safe.c
$ ./a.out
target = 1
Current host name: mylo
target = 0

After apply this patch:
$ hostname
$ gcc sysctl-safe.c
$ ./a.out
target = 1
Current host name: mylo
target = 1

Signed-off-by: Yi Yang <>

--- a/kernel/sysctl.c.orig 2005-12-30 09:21:34.000000000 +0000
+++ b/kernel/sysctl.c 2005-12-30 15:58:15.000000000 +0000
@@ -2207,8 +2207,6 @@ int sysctl_string(ctl_table *table, int
len = table->maxlen;
if(copy_to_user(oldval, table->data, len))
return -EFAULT;
- if(put_user(0, ((char __user *) oldval) + len))
- return -EFAULT;
if(put_user(len, oldlenp))
return -EFAULT;

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at
Please read the FAQ at

 \ /
  Last update: 2005-12-30 09:43    [W:0.071 / U:2.036 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site