Bugzilla – Bug 63813
VUL-0: CVE-2004-1151: kernel: buffer overrun in arch/x86_64/sys_ia32.c:sys32_ni_syscall()
Last modified: 2021-10-13 11:37:09 UTC
Hi, this one was sent to vendor-sec: From: Alan Cox <alan@lxorguk.ukuu.org.uk> To: vendor-sec@lst.de Subject: [vendor-sec] [Fwd: Buffer overrun in arch/x86_64/sys_ia32.c:sys32_ni_syscall()] Errors-To: vendor-sec-admin@lst.de Date: Tue, 30 Nov 2004 16:00:23 +0000 -----Forwarded Message----- > From: Jeremy Fitzhardinge <jeremy@goop.org> > To: linux-kernel <linux-kernel@vger.kernel.org> > Cc: Andrew Morton <akpm@osdl.org> > Subject: Buffer overrun in arch/x86_64/sys_ia32.c:sys32_ni_syscall() > Date: Mon, 29 Nov 2004 20:05:20 -0800 > > struct task_struct.comm is defined to be 16 chars, but > arch/x86_64/sys_ia32.c:sys32_ni_syscall() copies it into a static 8 byte > buffer, which will surely cause problems. This patch makes lastcomm[] > the right size, and makes sure it can't be overrun. Since the code also > goes to the effort of getting a local copy of current in "me", we may as > well use it for printing the message. > > Patch is against 2.6.10-rc2-mm3. > > J > > arch/x86_64/ia32/sys_ia32.c | 11 ++++++----- > 1 files changed, 6 insertions(+), 5 deletions(-) > > diff -puN arch/x86_64/ia32/sys_ia32.c~short-comm-string arch/x86_64/ia32/sys_ia32.c > --- local-2.6/arch/x86_64/ia32/sys_ia32.c~short-comm-string 2004-11-29 19:51:02.922621617 -0800 > +++ local-2.6-jeremy/arch/x86_64/ia32/sys_ia32.c 2004-11-29 19:52:43.493561830 -0800 > @@ -525,11 +525,12 @@ sys32_waitpid(compat_pid_t pid, unsigned > int sys32_ni_syscall(int call) > { > struct task_struct *me = current; > - static char lastcomm[8]; > - if (strcmp(lastcomm, me->comm)) { > - printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call, > - current->comm); > - strcpy(lastcomm, me->comm); > + static char lastcomm[sizeof(me->comm)]; > + > + if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) { > + printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call, > + me->comm); > + strncpy(lastcomm, me->comm, sizeof(lastcomm)); > } > return -ENOSYS; > } > > _ > > > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/
<!-- SBZ_reproduce --> -
From: Chris Wright <chrisw@osdl.org> To: Chris Wright <chrisw@osdl.org> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>, vendor-sec@lst.de Subject: Re: [vendor-sec] [Fwd: Buffer overrun in arch/x86_64/sys_ia32.c:sys32_ni_syscall()] User-Agent: Mutt/1.2.5i Errors-To: vendor-sec-admin@lst.de Date: Tue, 30 Nov 2004 10:38:35 -0800 * Chris Wright (chrisw@osdl.org) wrote: > There's at least one more in the same file. Looking for any more. Only found the one extra in sys32_vm86_warning. ===== arch/x86_64/ia32/sys_ia32.c 1.74 vs edited ===== --- 1.74/arch/x86_64/ia32/sys_ia32.c 2004-11-02 06:40:37 -08:00 +++ edited/arch/x86_64/ia32/sys_ia32.c 2004-11-30 09:42:26 -08:00 @@ -525,11 +525,12 @@ sys32_waitpid(compat_pid_t pid, unsigned int sys32_ni_syscall(int call) { struct task_struct *me = current; - static char lastcomm[8]; - if (strcmp(lastcomm, me->comm)) { - printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call, - current->comm); - strcpy(lastcomm, me->comm); + static char lastcomm[sizeof(me->comm)]; + + if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) { + printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", + call, me->comm); + strncpy(lastcomm, me->comm, sizeof(lastcomm)); } return -ENOSYS; } @@ -1125,11 +1126,11 @@ long sys32_fadvise64_64(int fd, __u32 of long sys32_vm86_warning(void) { struct task_struct *me = current; - static char lastcomm[8]; - if (strcmp(lastcomm, me->comm)) { + static char lastcomm[sizeof(me->comm)]; + if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) { printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n", me->comm); - strcpy(lastcomm, me->comm); + strncpy(lastcomm, me->comm, sizeof(lastcomm)); } return -ENOSYS; } _______________________________________________ Vendor Security mailing list
excuse the inline patches... that the way they were sent.
Is me->comm 0-terminated already?
the 0 termination is not really necessary, since most things operate on bytecounts. (except the printk, but this one is harmless, it will at max print some junk). Can someone please review these and apply ?
The patch is obviously correct. It is needed in all our 2.6 branches, and not in any of the 2.4 ones. Is there a coordinated disclosure date?
the first mail shows "to: linux-kernel", so it is public already. please commit.
Committed to all 2.6 based trees.
<!-- SBZ_reopen -->Reopened by meissner@suse.de at Thu Dec 2 14:45:28 2004, took initial reporter thomas@suse.de to cc
reopen for trackiung
====================================================== Candidate: CAN-2004-1151 URL: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-1151 Reference: MLIST:[linux-kernel] 20041130 Buffer overrun in +arch/x86_64/sys_ia32.c:sys32_ni_syscall() Reference: URL:http://www.ussg.iu.edu/hypermail/linux/kernel/0411.3/1467.html Reference: MISC:http://linux.bkbits.net:8080/linux-2.6/cset@1.2079 Reference: +MISC:http://linux.bkbits.net:8080/linux-2.6/gnupatch@41ae6af1cR3mJYlW6D8EHxCKSx+uJiQ Multiple buffer overflows in the (1) sys32_ni_syscall and (2) sys32_vm86_warning functions in sys_ia32.c for Linux 2.6.x have unknown impact with unknown attack vectors.
The problem is not a security hole because it only overflows a static variable and the static variables nearby are not exploitable in any way. It's a good idea to fix, but I very much doubt it is exploitable in anyways. I wish the vendor-sec people would do a bit more sanity checking before posting such panic reports.
*** Bug 64233 has been marked as a duplicate of this bug. ***
To give some more details the overflow happens into these variables: ffffffff805362e0 b df_list ffffffff805362e8 b lastcomm.0 ffffffff805362f0 b lastcomm.1 lastcomm is the variable of the other function. df_list is a list used by change_page_attr, which is normally only used during system bootup or when AGP aperture state is changed. The list is then walked this way: down_read(&init_mm.mmap_sem); df = xchg(&df_list, NULL); up_read(&init_mm.mmap_sem); flush_map((df && !df->next) ? df->address : 0); for (; df; df = next_df) { next_df = df->next; if (df->fpage) __free_page(df->fpage); kfree(df); } flush_map doesn't have any visible side effects. To do anything you would need to write a known address and then could possibly free something else. It is unlikely you can inject anything using that though. I am all for fixing real security issues, but always please do some sanity checking first before panicing even when it comes in on vendor-sec.
Actually the previous analysis was not quite correct. It overflows 8 bytes into the next, not the previous static variable. That would be ffffffff805362e8 b lastcomm.0 ffffffff805362f0 b lastcomm.1 ffffffff805362f8 b count.1 It's probably one of the count variables in fs/compat_ioctl.c overwriting these is completely harmless because they only control a printk. So in short I think it cannot be exploited in any ways.
Also can someone tell vendor-sec that so that the other vendors don't need to panic?
done
updates and advisory released.
CVE-2004-1151: CVSS v2 Base Score: 7.2 (AV:L/AC:L/Au:N/C:C/I:C/A:C)