Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 873

kernel-2.6.18-238.el5.src.rpm

From: Vitaly Mayatskikh <vmayatsk@redhat.com>
Date: Mon, 25 Aug 2008 10:15:51 +0200
Subject: [fs] binfmt_misc: avoid potential kernel stack overflow
Message-id: m38wulqzm0.fsf@gravicappa.englab.brq.redhat.com
O-Subject: Re: [RHEL-5.3 PATCH] BZ459463 kernel: binfmt_misc.c: avoid potential kernel stack overflow [rhel-5.3]
Bugzilla: 459463
RH-Acked-by: Larry Woodman <lwoodman@redhat.com>
RH-Acked-by: Eugene Teo <eteo@redhat.com>

Bugzilla: 459463
https://bugzilla.redhat.com/show_bug.cgi?id=459463

Description:
============

diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index 1f2d1ad..7f302b8 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -44,7 +44,7 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
 			return -ENOEXEC;
 	}
 
-	bprm->sh_bang++;	/* Well, the bang-shell is implicit... */
+	bprm->sh_bang = 1;	/* Well, the bang-shell is implicit... */
 	allow_write_access(bprm->file);
 	fput(bprm->file);
 	bprm->file = NULL;
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 1378ba3..2adf2ad 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -42,6 +42,9 @@ enum {Enabled, Magic};
 #define MISC_FMT_OPEN_BINARY (1<<30)
 #define MISC_FMT_CREDENTIALS (1<<29)
 
+/* Marker for breaking misc - > script -> misc loop */
+#define MISC_BANG (1<<1)
+
 typedef struct {
 	struct list_head list;
 	unsigned long flags;		/* type, status, etc. */
@@ -116,6 +119,10 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 	if (!enabled)
 		goto _ret;
 
+	retval = -ENOEXEC;
+	if (bprm->sh_bang & MISC_BANG)
+		goto _ret;
+
 	/* to keep locking time low, we copy the interpreter string */
 	read_lock(&entries_lock);
 	fmt = check_file(bprm);
@@ -201,6 +208,8 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 	if (retval < 0)
 		goto _error;
 
+	bprm->sh_bang |= MISC_BANG;
+
 	retval = search_binary_handler (bprm, regs);
 	if (retval < 0)
 		goto _error;
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 5b6309f..e2f55c1 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -30,7 +30,7 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 	 * Sorta complicated, but hopefully it will work.  -TYT
 	 */
 
-	bprm->sh_bang++;
+	bprm->sh_bang = 1;
 	allow_write_access(bprm->file);
 	fput(bprm->file);
 	bprm->file = NULL;