From: "Zach, Yoav" <yoav.zach@intel.com>

This patch allows for misc binaries to run with credentials and security
token that are calculated according to the binaries, and not according to the
interpreter, which is the legacy behavior of binfmt_misc.

The way it is done is by calling prepare_binprm, which is where these
attributes are calculated, before switching the 'file' field in the bprm from
the binary to the interpreter.

This feature should be used with care, since the interpreter will have root
permissions when running a setuid binary owned by root.

Please note - 

- Only root can register an interpreter with binfmt_misc.  The feature is
  documented and the administrator is advised to handle it with care

- The new feature is enabled only with a special flag in the registration
  string.  When this flag is not specified the current behavior of
  binfmt_misc is kept

- This is the only 'right' way for an interpreter to know the correct
  AT_SECURE value for the interpreted binary




---

 25-akpm/Documentation/binfmt_misc.txt |    7 +++++++
 25-akpm/fs/binfmt_misc.c              |   29 +++++++++++++++++++++++++++--
 2 files changed, 34 insertions(+), 2 deletions(-)

diff -puN Documentation/binfmt_misc.txt~binfmt_misc-credentials Documentation/binfmt_misc.txt
--- 25/Documentation/binfmt_misc.txt~binfmt_misc-credentials	Mon Mar  1 16:00:28 2004
+++ 25-akpm/Documentation/binfmt_misc.txt	Mon Mar  1 16:00:28 2004
@@ -48,6 +48,13 @@ Here is what the fields mean:
             the interpreter to execute non-readable binaries. This feature should
             be used with care - the interpreter has to be trusted not to emit
             the contents of the non-readable binary.
+      'C' - credentials. Currently, the behavior of binfmt_misc is to calculate
+            the credentials and security token of the new process according to
+            the interpreter. When this flag is included, these attributes are
+            calculated according to the binary. It also implies the 'O' flag.
+            This feature should be used with care as the interpreter
+            will run with root permissions when a setuid binary owned by root
+            is run with binfmt_misc.
 
 
 There are some restrictions:
diff -puN fs/binfmt_misc.c~binfmt_misc-credentials fs/binfmt_misc.c
--- 25/fs/binfmt_misc.c~binfmt_misc-credentials	Mon Mar  1 16:00:28 2004
+++ 25-akpm/fs/binfmt_misc.c	Mon Mar  1 16:00:28 2004
@@ -40,6 +40,7 @@ static int enabled = 1;
 enum {Enabled, Magic};
 #define MISC_FMT_PRESERVE_ARGV0 (1<<31)
 #define MISC_FMT_OPEN_BINARY (1<<30)
+#define MISC_FMT_CREDENTIALS (1<<29)
 
 typedef struct {
 	struct list_head list;
@@ -172,8 +173,22 @@ static int load_misc_binary(struct linux
 
 
 	binary_file = bprm->file;
-	bprm->file = interp_file;
-	retval = prepare_binprm(bprm);
+	if (fmt->flags & MISC_FMT_CREDENTIALS) {
+		/*
+		 * Call prepare_binprm before switching to interpreter's file
+		 * so that all security calculation will be done according to
+		 * binary and not interpreter
+		 */
+		retval = prepare_binprm(bprm);
+		if (retval < 0)
+			goto _error;
+		bprm->file = interp_file;
+		memset(bprm->buf, 0, BINPRM_BUF_SIZE);
+		retval = kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
+	} else {
+		bprm->file = interp_file;
+		retval = prepare_binprm (bprm);
+	}
 
 	if (retval < 0)
 		goto _error;
@@ -271,6 +286,13 @@ static inline char * check_special_flags
 				p++;
 				e->flags |= MISC_FMT_OPEN_BINARY;
 				break;
+			case 'C':
+				p++;
+				/* this flags also implies the
+				   open-binary flag */
+				e->flags |= (MISC_FMT_CREDENTIALS |
+						MISC_FMT_OPEN_BINARY);
+				break;
 			default:
 				cont = 0;
 		}
@@ -453,6 +475,9 @@ static void entry_status(Node *e, char *
 	if (e->flags & MISC_FMT_OPEN_BINARY) {
 		*dp ++ = 'O';
 	}
+	if (e->flags & MISC_FMT_CREDENTIALS) {
+		*dp ++ = 'C';
+	}
 	*dp ++ = '\n';
 
 

_