tag 319629 +patch thanks On Sat, Jul 23, 2005 at 10:42:24AM -0500, Micah Anderson wrote: > Package: kernel-source-2.4.27 > Version: 2.4.27-10 > Severity: normal > Tags: security > > http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-1768 reads: > > Race condition in the ia32 compatibility code for the execve system > call in Linux kernel 2.4 before 2.4.31 and 2.6 before 2.6.6 allows > local users to cause a denial of service (kernel panic) and possibly > execute arbitrary code via a concurrent thread that increments a > pointer count after the nargs function has counted the pointers, but > before the count is copied from user space to kernel space, which > leads to a buffer overflow. > > I looked in the pending Changelog for 2.4.27 and did not see this CAN > number listed. Please be sure to reference this CAN number in the > changelog when fixed, as you always do. > > Additional reference: > http://marc.theaimsgroup.com/?l=bugtraq&m=112110120216116&w=2
Thanks, I have put the attached patch into svn and it shold appear in the next release. amd64 does not have a 2.4 kernel (and techincally isn't part of sarge anyway) so only ia64 is affected. However the patch should fix both. -- Horms
commit 1e483bdd0ac8852a53e32e09059df9788619b3e8 tree 29e6ef82f987734d97da57af63a5f0410c21996c parent bb6c40830e2f66b33c22275829a730ed078e430a author Andi Kleen <[EMAIL PROTECTED]> 1119964612 +0200 committer Marcelo Tosatti <[EMAIL PROTECTED]> 1120052986 -0300 [PATCH] Fix buffer overflow in x86-64/ia64 32bit execve Fix buffer overflow in x86-64/ia64 32bit execve Originally noted by Ilja van Sprundel I fixed it for both x86-64 and IA64. Other architectures are not affected. Signed-off-by: Andi Kleen <[EMAIL PROTECTED]> I:100644 100644 d398d537c16b1a744e4bf76136d19d1d80c25099 acfa7e6bb6307923a3c6738b0c498d99c8ce890a M arch/ia64/ia32/sys_ia32.c R:100644 100644 0c43987ce7ab3032b96036c7d9d22b81a22a151f 3692043ab57ab273234a2af15dc2d01560f3297a M arch/x86_64/ia32/sys_ia32.c arch/x86_64/ia32/sys_ia32.c manually applied and rediffed for 2.4.27 for Debian - Horms 25th July 2005 Key: S: Skipped I: Included Included verbatim D: Deleted Manually deleted by subsequent user edit R: Revised Manually revised by subsequent user edit diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -94,7 +94,7 @@ asmlinkage unsigned long sys_brk(unsigne static DECLARE_MUTEX(ia32_mmap_sem); static int -nargs (unsigned int arg, char **ap) +nargs (unsigned int arg, char **ap, int max) { unsigned int addr; int n, err; @@ -107,6 +107,8 @@ nargs (unsigned int arg, char **ap) err = get_user(addr, (unsigned int *)A(arg)); if (err) return err; + if (n > max) + return -E2BIG; if (ap) *ap++ = (char *) A(addr); arg += sizeof(unsigned int); @@ -128,10 +130,11 @@ sys32_execve (char *filename, unsigned i int na, ne, len; long r; - na = nargs(argv, NULL); + /* Allocates upto 2x MAX_ARG_PAGES */ + na = nargs(argv, NULL, (MAX_ARG_PAGES*PAGE_SIZE) / sizeof(char *) - 1); if (na < 0) return na; - ne = nargs(envp, NULL); + ne = nargs(envp, NULL, (MAX_ARG_PAGES*PAGE_SIZE) / sizeof(char *) - 1 ); if (ne < 0) return ne; len = (na + ne + 2) * sizeof(*av); @@ -143,10 +146,10 @@ sys32_execve (char *filename, unsigned i av[na] = NULL; ae[ne] = NULL; - r = nargs(argv, av); + r = nargs(argv, av, na); if (r < 0) goto out; - r = nargs(envp, ae); + r = nargs(envp, ae, ne); if (r < 0) goto out; --- a/arch/x86_64/ia32/sys_ia32.c 2004-04-14 22:05:28.000000000 +0900 +++ b/arch/x86_64/ia32/sys_ia32.c 2005-07-25 17:29:16.000000000 +0900 @@ -2193,7 +2193,7 @@ return ret; } -static int nargs(u32 src, char **dst) +static int nargs(u32 src, char **dst, int max) { int cnt; u32 val; @@ -2207,7 +2207,7 @@ dst[cnt] = (char *)(u64)val; cnt++; src += 4; - if (cnt >= (MAX_ARG_PAGES*PAGE_SIZE)/sizeof(void*)) + if (cnt > max) return -E2BIG; } while(val); if (dst) @@ -2223,13 +2223,14 @@ int ret; unsigned sz = 0; + /* Can actually allocate 2*MAX_ARG_PAGES */ if (argv) { - na = nargs(argv, NULL); + na = nargs(argv, NULL, (MAX_ARG_PAGES * PAGE_SIZE)/sizeof(char*) - 1); if (na < 0) return -EFAULT; } if (envp) { - ne = nargs(envp, NULL); + ne = nargs(envp, NULL, (MAX_ARG_PAGES * PAGE_SIZE)/sizeof(char*) - 1); if (ne < 0) return -EFAULT; } @@ -2245,13 +2246,13 @@ } if (argv) { - ret = nargs(argv, buf); + ret = nargs(argv, buf, na); if (ret < 0) goto free; } if (envp) { - ret = nargs(envp, buf + na); + ret = nargs(envp, buf + na, ne); if (ret < 0) goto free; }