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=bugtraqm=112110120216116w=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.0 +0900
+++ b/arch/x86_64/ia32/sys_ia32.c 2005-07-25 17:29:16.0 +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