public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Fix user data corrupted by old value return of sysctl
@ 2005-12-30  8:40 Yi Yang
  2005-12-30 17:25 ` Linus Torvalds
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Yi Yang @ 2005-12-30  8:40 UTC (permalink / raw)
  To: linux-kernel; +Cc: torvalds, gregkh, akpm

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[])
{
	myos.target = 1;
	printf("target = %d\n", myos.target);
	myos.osnamelth = SIZE(myos.osname);
         if (sysctl(name, SIZE(name), myos.osname,
			&myos.osnamelth, 0, 0))
                 perror("sysctl");
	else {
                 printf("Current host name: %s\n", myos.osname);
	}
	printf("target = %d\n", myos.target);
         return 0;
}

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

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

Signed-off-by: Yi Yang <yang.y.yi@gmail.com>


--- 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;
  		}




^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2006-01-04  1:41 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-30  8:40 [PATCH] Fix user data corrupted by old value return of sysctl Yi Yang
2005-12-30 17:25 ` Linus Torvalds
2005-12-31  1:08   ` Yi Yang
2005-12-31  9:25   ` Coywolf Qi Hunt
2005-12-31 11:47   ` YOSHIFUJI Hideaki / 吉藤英明
2005-12-30 22:31 ` David Wagner
2005-12-31  9:13 ` Coywolf Qi Hunt
2005-12-31  9:26   ` Yi Yang
2005-12-31  9:44     ` Coywolf Qi Hunt
2006-01-04  1:41       ` Yi Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox