Skip to content

Commit 2347961

Browse files
vivierhdeller
authored andcommitted
binfmt_misc: pass binfmt_misc flags to the interpreter
It can be useful to the interpreter to know which flags are in use. For instance, knowing if the preserve-argv[0] is in use would allow to skip the pathname argument. This patch uses an unused auxiliary vector, AT_FLAGS, to add a flag to inform interpreter if the preserve-argv[0] is enabled. Note by Helge Deller: The real-world user of this patch is qemu-user, which needs to know if it has to preserve the argv[0]. See Debian bug #970460. Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: YunQiang Su <ysu@wavecomp.com> URL: http://bugs.debian.org/970460 Signed-off-by: Helge Deller <deller@gmx.de>
1 parent b779507 commit 2347961

File tree

5 files changed

+19
-3
lines changed

5 files changed

+19
-3
lines changed

fs/binfmt_elf.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
186186
unsigned char k_rand_bytes[16];
187187
int items;
188188
elf_addr_t *elf_info;
189+
elf_addr_t flags = 0;
189190
int ei_index;
190191
const struct cred *cred = current_cred();
191192
struct vm_area_struct *vma;
@@ -260,7 +261,9 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
260261
NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
261262
NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
262263
NEW_AUX_ENT(AT_BASE, interp_load_addr);
263-
NEW_AUX_ENT(AT_FLAGS, 0);
264+
if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
265+
flags |= AT_FLAGS_PRESERVE_ARGV0;
266+
NEW_AUX_ENT(AT_FLAGS, flags);
264267
NEW_AUX_ENT(AT_ENTRY, e_entry);
265268
NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
266269
NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));

fs/binfmt_elf_fdpic.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
506506
char __user *u_platform, *u_base_platform, *p;
507507
int loop;
508508
int nr; /* reset for each csp adjustment */
509+
unsigned long flags = 0;
509510

510511
#ifdef CONFIG_MMU
511512
/* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
@@ -648,7 +649,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
648649
NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
649650
NEW_AUX_ENT(AT_PHNUM, exec_params->hdr.e_phnum);
650651
NEW_AUX_ENT(AT_BASE, interp_params->elfhdr_addr);
651-
NEW_AUX_ENT(AT_FLAGS, 0);
652+
if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
653+
flags |= AT_FLAGS_PRESERVE_ARGV0;
654+
NEW_AUX_ENT(AT_FLAGS, flags);
652655
NEW_AUX_ENT(AT_ENTRY, exec_params->entry_addr);
653656
NEW_AUX_ENT(AT_UID, (elf_addr_t) from_kuid_munged(cred->user_ns, cred->uid));
654657
NEW_AUX_ENT(AT_EUID, (elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid));

fs/binfmt_misc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ static int load_misc_binary(struct linux_binprm *bprm)
153153
if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
154154
goto ret;
155155

156-
if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
156+
if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
157+
bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
158+
} else {
157159
retval = remove_arg_zero(bprm);
158160
if (retval)
159161
goto ret;

include/linux/binfmts.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ struct linux_binprm {
7373
#define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
7474
#define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
7575

76+
/* preserve argv0 for the interpreter */
77+
#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
78+
#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
79+
7680
/* Function parameter for binfmt->coredump */
7781
struct coredump_params {
7882
const kernel_siginfo_t *siginfo;

include/uapi/linux/binfmts.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@ struct pt_regs;
1818
/* sizeof(linux_binprm->buf) */
1919
#define BINPRM_BUF_SIZE 256
2020

21+
/* preserve argv0 for the interpreter */
22+
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
23+
#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
24+
2125
#endif /* _UAPI_LINUX_BINFMTS_H */

0 commit comments

Comments
 (0)