[PATCH] sys_hpux: fix strlen_user() race
authorKyle McMartin <kyle@mcmartin.ca>
Tue, 7 Feb 2006 20:58:47 +0000 (12:58 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 8 Feb 2006 00:12:33 +0000 (16:12 -0800)
Userspace can alter the string after the kernel has run strlen_user().

Also: the strlen_user() return value includes the \0, so fix that.

Also: handle EFAULT from strlen_user().

It's unlikely anyone is using this code.  Very, very unlikely.  If I
remember correctly, CONFIG_HPUX turns this code on, but one would actually
need CONFIG_BINFMT_SOM to load a binary that could cause a problem, and
BINFMT_SOM has had an #error in it for quite some time.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/parisc/hpux/sys_hpux.c

index 29b4d61898f2ca0b76e64dda8abcbab7ac48a76e..05273ccced0e56aeb00779111fac12aa62ead419 100644 (file)
@@ -468,19 +468,23 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
        if ( opcode == 1 ) { /* GETFSIND */     
                len = strlen_user((char *)arg1);
                printk(KERN_DEBUG "len of arg1 = %d\n", len);
-
-               fsname = (char *) kmalloc(len+1, GFP_KERNEL);
+               if (len == 0)
+                       return 0;
+               fsname = (char *) kmalloc(len, GFP_KERNEL);
                if ( !fsname ) {
                        printk(KERN_DEBUG "failed to kmalloc fsname\n");
                        return 0;
                }
 
-               if ( copy_from_user(fsname, (char *)arg1, len+1) ) {
+               if ( copy_from_user(fsname, (char *)arg1, len) ) {
                        printk(KERN_DEBUG "failed to copy_from_user fsname\n");
                        kfree(fsname);
                        return 0;
                }
 
+               /* String could be altered by userspace after strlen_user() */
+               fsname[len] = '\0';
+
                printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
                if ( !strcmp(fsname, "hfs") ) {
                        fstype = 0;