From: "Zach, Yoav" 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'; _