linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: P J P <ppandit@redhat.com>
To: Kees Cook <keescook@chromium.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
	linux-kernel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Josh Triplett <josh@joshtriplett.org>,
	Serge Hallyn <serge.hallyn@canonical.com>,
	linux-fsdevel@vger.kernel.org, halfdog <me@halfdog.net>
Subject: Re: [PATCH] exec: do not leave bprm->interp on stack
Date: Thu, 25 Oct 2012 17:16:22 +0530 (IST)	[thread overview]
Message-ID: <alpine.LFD.2.02.1210251636480.23155@wniryva.cad.erqung.pbz> (raw)
In-Reply-To: <CAGXu5jLwvcpyMp8RcF8aFySKkkj+17ovNOvC_r88+D0fQW7CsQ@mail.gmail.com>


  Hello Kees,

+-- On Wed, 24 Oct 2012, Kees Cook wrote --+
| What should the code here _actually_ be doing? The _script and _misc 
| handlers expect to rewrite the bprm contents and recurse, but the module 
| loader want to try again. It's not clear to me what the binfmt module 
| handler is even there for; I don't see any binfmt-XXXX aliases in the tree. 
| If nothing uses it, should we just rip it out? That would solve it too.

I've been following this issue and updated versions of HDs patch. Below is a 
small patch to search_binary_handler() routine, which attempts to make the 
request_module call before calling load_script routine.

Besides fixing the stack disclosure issue it also helps to *simplify* the 
search_binary_handler routine by removing the -for (try=0;try<2;try++)- loop.

I'd really appreciate any comments/suggestions you may have.

===
diff --git a/fs/exec.c b/fs/exec.c
index 8b9011b..e368f41 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1369,65 +1369,55 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
 	old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
 	rcu_read_unlock();
 
-	retval = -ENOENT;
-	for (try=0; try<2; try++) {
-		read_lock(&binfmt_lock);
-		list_for_each_entry(fmt, &formats, lh) {
-			int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
-			if (!fn)
-				continue;
-			if (!try_module_get(fmt->module))
-				continue;
-			read_unlock(&binfmt_lock);
-			retval = fn(bprm, regs);
-			/*
-			 * Restore the depth counter to its starting value
-			 * in this call, so we don't have to rely on every
-			 * load_binary function to restore it on return.
-			 */
-			bprm->recursion_depth = depth;
-			if (retval >= 0) {
-				if (depth == 0) {
-					trace_sched_process_exec(current, old_pid, bprm);
-					ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
-				}
-				put_binfmt(fmt);
-				allow_write_access(bprm->file);
-				if (bprm->file)
-					fput(bprm->file);
-				bprm->file = NULL;
-				current->did_exec = 1;
-				proc_exec_connector(current);
-				return retval;
-			}
-			read_lock(&binfmt_lock);
-			put_binfmt(fmt);
-			if (retval != -ENOEXEC || bprm->mm == NULL)
-				break;
-			if (!bprm->file) {
-				read_unlock(&binfmt_lock);
-				return retval;
-			}
-		}
-		read_unlock(&binfmt_lock);
 #ifdef CONFIG_MODULES
-		if (retval != -ENOEXEC || bprm->mm == NULL) {
-			break;
-		} else {
-#define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))
-			if (printable(bprm->buf[0]) &&
-			    printable(bprm->buf[1]) &&
-			    printable(bprm->buf[2]) &&
-			    printable(bprm->buf[3]))
-				break; /* -ENOEXEC */
-			if (try)
-				break; /* -ENOEXEC */
-			request_module("binfmt-%04x", *(unsigned short *)(&bprm->buf[2]));
-		}
-#else
-		break;
+#define printable(c) (0x20<=(c) && (c)<=0x7e)
+
+    if (printable(bprm->buf[0]) && printable(bprm->buf[1])
+        && printable(bprm->buf[2]) && printable(bprm->buf[3]))
+        request_module("binfmt-%04x", *(unsigned short *)(&bprm->buf[2]));
 #endif
-	}
+
+    retval = -ENOENT;
+    read_lock(&binfmt_lock);
+    list_for_each_entry(fmt, &formats, lh) {
+        int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
+        if (!fn)
+            continue;
+        if (!try_module_get(fmt->module))
+            continue;
+        read_unlock(&binfmt_lock);
+        retval = fn(bprm, regs);
+        /*
+         * Restore the depth counter to its starting value
+         * in this call, so we don't have to rely on every
+         * load_binary function to restore it on return.
+         */
+        bprm->recursion_depth = depth;
+        if (retval >= 0) {
+            if (depth == 0) {
+                trace_sched_process_exec(current, old_pid, bprm);
+                ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
+            }
+            put_binfmt(fmt);
+            allow_write_access(bprm->file);
+            if (bprm->file)
+                fput(bprm->file);
+            bprm->file = NULL;
+            current->did_exec = 1;
+            proc_exec_connector(current);
+            return retval;
+        }
+        read_lock(&binfmt_lock);
+        put_binfmt(fmt);
+        if (retval != -ENOEXEC || bprm->mm == NULL)
+            break;
+        if (!bprm->file) {
+            read_unlock(&binfmt_lock);
+            return retval;
+        }
+    }
+    read_unlock(&binfmt_lock);
+
 	return retval;
 }
 
===

Thank you.
--
Prasad J Pandit / Red Hat Security Response Team
DB7A 84C5 D3F9 7CD1 B5EB  C939 D048 7860 3655 602B

  reply	other threads:[~2012-10-25 11:46 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-24 23:20 [PATCH] exec: do not leave bprm->interp on stack Kees Cook
2012-10-25  4:16 ` Al Viro
2012-10-25  6:21   ` Kees Cook
2012-10-25 11:46     ` P J P [this message]
2012-10-25 12:03       ` Tetsuo Handa
2012-10-25 12:57         ` P J P
2012-10-25 12:09       ` Al Viro
2012-10-25 12:38         ` Al Viro
2012-10-26 17:38           ` P J P
2012-10-26 18:36             ` Al Viro
2012-10-27 10:47               ` P J P
2012-10-27 17:05                 ` Kees Cook
2012-10-27 20:16                   ` P J P
2012-10-28  3:32                     ` Kees Cook
2012-11-06  8:10                       ` P J P
2012-11-12 22:10                         ` Kees Cook
2012-11-13  6:50                           ` halfdog
2012-11-16 12:50                           ` P J P
2012-11-16 18:00                             ` Kees Cook
2012-11-18 19:04                               ` P J P
2012-11-18 19:34                                 ` Kees Cook
2012-11-19  6:57                                   ` P J P
2012-11-19 20:41                                     ` Kees Cook
2012-11-20  7:04                                       ` P J P
2012-11-22 20:06                                       ` P J P
2012-11-23 18:43                                       ` P J P
2012-11-23 23:12                                         ` Tetsuo Handa
     [not found]                                       ` <alpine.LFD.2.02.1211221934220.19768@wniryva.cad.erqung.pbz>
     [not found]                                         ` <CAGXu5jL8zCt5ghW4ODPL9+SyC9+mbuw=4JMUngepY5fC8pSikQ@mail.gmail.com>
2012-11-26  7:09                                           ` P J P
     [not found]                                     ` <CA+55aFx3LFH5Xj1OkNoy7vN5w8y5tH39MUDujKqF3BdnmYibLQ@mail.gmail.com>
2012-11-20  7:08                                       ` P J P

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.LFD.2.02.1210251636480.23155@wniryva.cad.erqung.pbz \
    --to=ppandit@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=josh@joshtriplett.org \
    --cc=keescook@chromium.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=me@halfdog.net \
    --cc=serge.hallyn@canonical.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).