aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle McMartin <kyle@mcmartin.ca>2006-02-07 15:58:47 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-07 19:12:33 -0500
commit1fcbf053e55e961112f237dc690129f0858156f1 (patch)
treec352b63dc2d73e4033d064bb4b5437d76157bfa8
parentb5173119ff10c5538e92a7957a50887ae170b8da (diff)
[PATCH] sys_hpux: fix strlen_user() race
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>
-rw-r--r--arch/parisc/hpux/sys_hpux.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
index 29b4d61898f2..05273ccced0e 100644
--- a/arch/parisc/hpux/sys_hpux.c
+++ b/arch/parisc/hpux/sys_hpux.c
@@ -468,19 +468,23 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
468 if ( opcode == 1 ) { /* GETFSIND */ 468 if ( opcode == 1 ) { /* GETFSIND */
469 len = strlen_user((char *)arg1); 469 len = strlen_user((char *)arg1);
470 printk(KERN_DEBUG "len of arg1 = %d\n", len); 470 printk(KERN_DEBUG "len of arg1 = %d\n", len);
471 471 if (len == 0)
472 fsname = (char *) kmalloc(len+1, GFP_KERNEL); 472 return 0;
473 fsname = (char *) kmalloc(len, GFP_KERNEL);
473 if ( !fsname ) { 474 if ( !fsname ) {
474 printk(KERN_DEBUG "failed to kmalloc fsname\n"); 475 printk(KERN_DEBUG "failed to kmalloc fsname\n");
475 return 0; 476 return 0;
476 } 477 }
477 478
478 if ( copy_from_user(fsname, (char *)arg1, len+1) ) { 479 if ( copy_from_user(fsname, (char *)arg1, len) ) {
479 printk(KERN_DEBUG "failed to copy_from_user fsname\n"); 480 printk(KERN_DEBUG "failed to copy_from_user fsname\n");
480 kfree(fsname); 481 kfree(fsname);
481 return 0; 482 return 0;
482 } 483 }
483 484
485 /* String could be altered by userspace after strlen_user() */
486 fsname[len] = '\0';
487
484 printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname); 488 printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
485 if ( !strcmp(fsname, "hfs") ) { 489 if ( !strcmp(fsname, "hfs") ) {
486 fstype = 0; 490 fstype = 0;