Package: binfmt-support Version: 2.1.4-1 Severity: important Tags: patch Qemu will start requiring setting P in binfmt_misc flags [P]. Unfortunately update-binfmts doesn't just pass flags section as-is. The only supported flag so far is credentials, which is supported via --credentials command line flag.
I've implemented a similar --preserve flag in the attached patch. This patch (or something similar) needs to land to Debian before qemu 2.2 can be uploaded, or user-mode emulation will break. Riku [P] https://www.kernel.org/doc/Documentation/binfmt_misc.txt
>From 76ac76a0d52cad3b555a8f1d0822cf1fcf884d77 Mon Sep 17 00:00:00 2001 From: Riku Voipio <[email protected]> Date: Fri, 15 Aug 2014 13:22:44 +0300 Subject: [PATCH] Add support for preserve-argv0 flag Qemu will start requiring setting P in binfmt_misc flags [P]. Unfortunately update-binfmts doesn't just pass flags section as-is. The only supported flag so far is credentials, which is supported via --credentials command line flag. I've implemented a similar --preserve flag in this commit. This commit (or something similar) needs to land to Debian before qemu 2.2 can be uploaded. [P] https://www.kernel.org/doc/Documentation/binfmt_misc.txt Signed-off-by: Riku Voipio <[email protected]> --- src/format.c | 5 +++++ src/format.h | 1 + src/tests/detectors | 3 +++ src/tests/display | 2 ++ src/tests/enable | 2 ++ src/tests/import | 2 ++ src/tests/install | 4 ++++ src/update-binfmts.c | 18 +++++++++++++++--- 8 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/format.c b/src/format.c index d7620b0..0bfdfe1 100644 --- a/src/format.c +++ b/src/format.c @@ -76,6 +76,7 @@ struct binfmt *binfmt_load (const char *name, const char *filename, int quiet) READ_LINE (interpreter, 0); READ_LINE (detector, 1); READ_LINE (credentials, 1); + READ_LINE (preserve, 1); #undef READ_LINE @@ -106,6 +107,7 @@ struct binfmt *binfmt_new (const char *name, Hash_table *args) SET_FIELD (interpreter); SET_FIELD (detector); SET_FIELD (credentials); + SET_FIELD (preserve); #undef SET_FIELD @@ -179,6 +181,7 @@ int binfmt_write (const struct binfmt *binfmt, const char *filename) WRITE_FIELD (interpreter); WRITE_FIELD (detector); WRITE_FIELD (credentials); + WRITE_FIELD (preserve); #undef WRITE_FIELD @@ -203,6 +206,7 @@ void binfmt_print (const struct binfmt *binfmt) PRINT_FIELD (interpreter); PRINT_FIELD (detector); PRINT_FIELD (credentials); + PRINT_FIELD (preserve); #undef PRINT_FIELD } @@ -226,6 +230,7 @@ void binfmt_free (struct binfmt *binfmt) free (binfmt->interpreter); free (binfmt->detector); free (binfmt->credentials); + free (binfmt->preserve); free (binfmt); } diff --git a/src/format.h b/src/format.h index 2d1e3e6..54a09e0 100644 --- a/src/format.h +++ b/src/format.h @@ -31,6 +31,7 @@ struct binfmt { char *interpreter; char *detector; char *credentials; + char *preserve; }; struct binfmt *binfmt_load (const char *name, const char *filename, int quiet); diff --git a/src/tests/detectors b/src/tests/detectors index 4bcfdc6..f3481f8 100755 --- a/src/tests/detectors +++ b/src/tests/detectors @@ -59,6 +59,7 @@ ext $tmpdir/program-1 $tmpdir/detector-1 + EOF expect_pass 'detector 1: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test-1" "$tmpdir/1-admin.exp"' @@ -82,6 +83,7 @@ ext $tmpdir/program-2 $tmpdir/detector-2 + EOF expect_pass 'detector 2: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test-2" "$tmpdir/2-admin.exp"' @@ -105,6 +107,7 @@ ext $tmpdir/program-3 + EOF expect_pass 'no detector: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test-3" "$tmpdir/3-admin.exp"' diff --git a/src/tests/display b/src/tests/display index 3844f04..4df4a25 100755 --- a/src/tests/display +++ b/src/tests/display @@ -37,6 +37,7 @@ ABCD /bin/sh + EOF expect_pass 'magic: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test-magic" "$tmpdir/1-admin.exp"' @@ -61,6 +62,7 @@ ext /bin/sh + EOF expect_pass 'extension with package: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test-extension" "$tmpdir/2-admin.exp"' diff --git a/src/tests/enable b/src/tests/enable index d709a16..b5c08dd 100755 --- a/src/tests/enable +++ b/src/tests/enable @@ -37,6 +37,7 @@ ABCD /bin/sh + EOF expect_pass 'magic: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test-magic" "$tmpdir/1-admin.exp"' @@ -61,6 +62,7 @@ ext /bin/sh + EOF expect_pass 'extension: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test-extension" "$tmpdir/2-admin.exp"' diff --git a/src/tests/import b/src/tests/import index cd33ab0..dde5e59 100755 --- a/src/tests/import +++ b/src/tests/import @@ -42,6 +42,7 @@ ABCD /bin/sh + EOF expect_pass 'magic: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test-magic" "$tmpdir/1-admin.exp"' @@ -72,6 +73,7 @@ ABCD /bin/sh + EOF expect_pass 'magic with mask: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test-magic-mask" "$tmpdir/2-admin.exp"' diff --git a/src/tests/install b/src/tests/install index ecaa456..5659679 100755 --- a/src/tests/install +++ b/src/tests/install @@ -37,6 +37,7 @@ ABCD /bin/sh + EOF expect_pass 'magic: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test" "$tmpdir/1-admin.exp"' @@ -67,6 +68,7 @@ ABCD /bin/sh + EOF expect_pass 'magic with offset and mask: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test" "$tmpdir/2-admin.exp"' @@ -98,6 +100,7 @@ ext /bin/sh + EOF expect_pass 'extension: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test" "$tmpdir/3-admin.exp"' @@ -133,6 +136,7 @@ ext /bin/sh + EOF expect_pass 'extension with package: admindir entry OK' \ 'diff -u "$tmpdir/var/lib/binfmts/test" "$tmpdir/4-admin.exp"' diff --git a/src/update-binfmts.c b/src/update-binfmts.c index 96ff1e0..8c11a86 100644 --- a/src/update-binfmts.c +++ b/src/update-binfmts.c @@ -362,6 +362,7 @@ static int act_enable (const char *name) int need_detector; const char *interpreter; const char *flags; + const char *preserve; char *regstring; procdir_name = xasprintf ("%s/%s", procdir, name); @@ -411,11 +412,13 @@ static int act_enable (const char *name) /* Fake the interpreter if we need a userspace detector program. */ interpreter = need_detector ? run_detectors : binfmt->interpreter; + preserve = (binfmt->preserve && !strcmp (binfmt->preserve, "yes")) + ? "P" : ""; flags = (binfmt->credentials && !strcmp (binfmt->credentials, "yes")) ? "C" : ""; - regstring = xasprintf (":%s:%c:%s:%s:%s:%s:%s\n", + regstring = xasprintf (":%s:%c:%s:%s:%s:%s:%s%s\n", name, type, binfmt->offset, binfmt->magic, - binfmt->mask, interpreter, flags); + binfmt->mask, interpreter, flags, preserve); if (test) printf ("enable %s with the following format string:\n %s", name, regstring); @@ -827,7 +830,8 @@ enum opts { OPT_ADMINDIR, OPT_IMPORTDIR, OPT_PROCDIR, - OPT_TEST + OPT_TEST, + OPT_PRESERVE }; static struct argp_option options[] = { @@ -863,6 +867,8 @@ static struct argp_option options[] = { "use this userspace detector program" }, { "credentials", OPT_CREDENTIALS, "YES/NO", OPTION_HIDDEN, "use credentials of original binary for interpreter (yes/no)" }, + { "preserve", OPT_PRESERVE, "YES/NO", OPTION_HIDDEN, + "preserve argv0 of original binary for interpreter (yes/no)" }, { "package", OPT_PACKAGE, "PACKAGE-NAME", 0, "for --install and --remove, specify the current package name", 1 }, { "admindir", OPT_ADMINDIR, "DIRECTORY", 0, @@ -888,6 +894,7 @@ static struct { const char *interpreter; const char *detector; const char *credentials; + const char *preserve; } spec; static const char *mode_name (enum opts m) @@ -1012,6 +1019,10 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) spec.credentials = arg; return 0; + case OPT_PRESERVE: + spec.preserve = arg; + return 0; + case OPT_PACKAGE: if (package) argp_error (state, "more than one --package option given"); @@ -1123,6 +1134,7 @@ int main (int argc, char **argv) ADD_SPEC (interpreter); ADD_SPEC (detector); ADD_SPEC (credentials); + ADD_SPEC (preserve); #undef ADD_SPEC binfmt = binfmt_new (name, format_args); -- 2.0.1

