linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter
@ 2020-01-28 13:25 Laurent Vivier
  2020-02-02 12:15 ` [EXTERNAL][PATCH " YunQiang Su
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Laurent Vivier @ 2020-01-28 13:25 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fsdevel, YunQiang Su, YunQiang Su, Alexander Viro,
	James Bottomley, Laurent Vivier

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.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---

Notes:
    This can be tested with QEMU from my branch:
    
      https://github.com/vivier/qemu/commits/binfmt-argv0
    
    With something like:
    
      # cp ..../qemu-ppc /chroot/powerpc/jessie
    
      # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
                            --persistent no --preserve-argv0 yes
      # systemctl restart systemd-binfmt.service
      # cat /proc/sys/fs/binfmt_misc/qemu-ppc
      enabled
      interpreter //qemu-ppc
      flags: POC
      offset 0
      magic 7f454c4601020100000000000000000000020014
      mask ffffffffffffff00fffffffffffffffffffeffff
      # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
      sh
    
      # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
                            --persistent no --preserve-argv0 no
      # systemctl restart systemd-binfmt.service
      # cat /proc/sys/fs/binfmt_misc/qemu-ppc
      enabled
      interpreter //qemu-ppc
      flags: OC
      offset 0
      magic 7f454c4601020100000000000000000000020014
      mask ffffffffffffff00fffffffffffffffffffeffff
      # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
      /bin/sh
    
    v3: mix my patch with one from YunQiang Su and my comments on it
        introduce a new flag in the uabi for the AT_FLAGS
    v2: only pass special flags (remove Magic and Enabled flags)

 fs/binfmt_elf.c              | 5 ++++-
 fs/binfmt_elf_fdpic.c        | 5 ++++-
 fs/binfmt_misc.c             | 4 +++-
 include/linux/binfmts.h      | 4 ++++
 include/uapi/linux/binfmts.h | 4 ++++
 5 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index ecd8d2698515..ff918042ceed 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -176,6 +176,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
 	unsigned char k_rand_bytes[16];
 	int items;
 	elf_addr_t *elf_info;
+	elf_addr_t flags = 0;
 	int ei_index = 0;
 	const struct cred *cred = current_cred();
 	struct vm_area_struct *vma;
@@ -250,7 +251,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
 	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
 	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
 	NEW_AUX_ENT(AT_BASE, interp_load_addr);
-	NEW_AUX_ENT(AT_FLAGS, 0);
+	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
+		flags |= AT_FLAGS_PRESERVE_ARGV0;
+	NEW_AUX_ENT(AT_FLAGS, flags);
 	NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
 	NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
 	NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 240f66663543..abb90d82aa58 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -507,6 +507,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
 	char __user *u_platform, *u_base_platform, *p;
 	int loop;
 	int nr;	/* reset for each csp adjustment */
+	unsigned long flags = 0;
 
 #ifdef CONFIG_MMU
 	/* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
@@ -647,7 +648,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
 	NEW_AUX_ENT(AT_PHENT,	sizeof(struct elf_phdr));
 	NEW_AUX_ENT(AT_PHNUM,	exec_params->hdr.e_phnum);
 	NEW_AUX_ENT(AT_BASE,	interp_params->elfhdr_addr);
-	NEW_AUX_ENT(AT_FLAGS,	0);
+	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
+		flags |= AT_FLAGS_PRESERVE_ARGV0;
+	NEW_AUX_ENT(AT_FLAGS,	flags);
 	NEW_AUX_ENT(AT_ENTRY,	exec_params->entry_addr);
 	NEW_AUX_ENT(AT_UID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->uid));
 	NEW_AUX_ENT(AT_EUID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid));
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index cdb45829354d..b9acdd26a654 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -154,7 +154,9 @@ static int load_misc_binary(struct linux_binprm *bprm)
 	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
 		goto ret;
 
-	if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
+	if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
+		bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
+	} else {
 		retval = remove_arg_zero(bprm);
 		if (retval)
 			goto ret;
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index b40fc633f3be..265b80d5fd6f 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -78,6 +78,10 @@ struct linux_binprm {
 #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
 #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
 
+/* if preserve the argv0 for the interpreter  */
+#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
+#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
+
 /* Function parameter for binfmt->coredump */
 struct coredump_params {
 	const kernel_siginfo_t *siginfo;
diff --git a/include/uapi/linux/binfmts.h b/include/uapi/linux/binfmts.h
index 689025d9c185..a70747416130 100644
--- a/include/uapi/linux/binfmts.h
+++ b/include/uapi/linux/binfmts.h
@@ -18,4 +18,8 @@ struct pt_regs;
 /* sizeof(linux_binprm->buf) */
 #define BINPRM_BUF_SIZE 256
 
+/* if preserve the argv0 for the interpreter  */
+#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
+#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
+
 #endif /* _UAPI_LINUX_BINFMTS_H */
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [EXTERNAL][PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter
  2020-01-28 13:25 [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter Laurent Vivier
@ 2020-02-02 12:15 ` YunQiang Su
  2020-02-14 12:29 ` [PATCH " Laurent Vivier
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: YunQiang Su @ 2020-02-02 12:15 UTC (permalink / raw)
  To: Laurent Vivier, linux-kernel
  Cc: linux-fsdevel, Alexander Viro, James Bottomley

在 2020-01-28二的 14:25 +0100,Laurent Vivier写道:
> 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.
> 
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>

Reviewed-by: YunQiang Su <ysu@wavecomp.com>

> ---
> 
> Notes:
>     This can be tested with QEMU from my branch:
>     
>       https://github.com/vivier/qemu/commits/binfmt-argv0
>     
>     With something like:
>     
>       # cp ..../qemu-ppc /chroot/powerpc/jessie
>     
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential
> yes \
>                             --persistent no --preserve-argv0 yes
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: POC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       sh
>     
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential
> yes \
>                             --persistent no --preserve-argv0 no
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: OC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       /bin/sh
>     
>     v3: mix my patch with one from YunQiang Su and my comments on it
>         introduce a new flag in the uabi for the AT_FLAGS
>     v2: only pass special flags (remove Magic and Enabled flags)
> 
>  fs/binfmt_elf.c              | 5 ++++-
>  fs/binfmt_elf_fdpic.c        | 5 ++++-
>  fs/binfmt_misc.c             | 4 +++-
>  include/linux/binfmts.h      | 4 ++++
>  include/uapi/linux/binfmts.h | 4 ++++
>  5 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index ecd8d2698515..ff918042ceed 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -176,6 +176,7 @@ create_elf_tables(struct linux_binprm *bprm,
> struct elfhdr *exec,
>  	unsigned char k_rand_bytes[16];
>  	int items;
>  	elf_addr_t *elf_info;
> +	elf_addr_t flags = 0;
>  	int ei_index = 0;
>  	const struct cred *cred = current_cred();
>  	struct vm_area_struct *vma;
> @@ -250,7 +251,9 @@ create_elf_tables(struct linux_binprm *bprm,
> struct elfhdr *exec,
>  	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
>  	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
>  	NEW_AUX_ENT(AT_BASE, interp_load_addr);
> -	NEW_AUX_ENT(AT_FLAGS, 0);
> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
> +	NEW_AUX_ENT(AT_FLAGS, flags);
>  	NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
>  	NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred-
> >uid));
>  	NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred-
> >euid));
> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
> index 240f66663543..abb90d82aa58 100644
> --- a/fs/binfmt_elf_fdpic.c
> +++ b/fs/binfmt_elf_fdpic.c
> @@ -507,6 +507,7 @@ static int create_elf_fdpic_tables(struct
> linux_binprm *bprm,
>  	char __user *u_platform, *u_base_platform, *p;
>  	int loop;
>  	int nr;	/* reset for each csp adjustment */
> +	unsigned long flags = 0;
>  
>  #ifdef CONFIG_MMU
>  	/* In some cases (e.g. Hyper-Threading), we want to avoid L1
> evictions
> @@ -647,7 +648,9 @@ static int create_elf_fdpic_tables(struct
> linux_binprm *bprm,
>  	NEW_AUX_ENT(AT_PHENT,	sizeof(struct elf_phdr));
>  	NEW_AUX_ENT(AT_PHNUM,	exec_params->hdr.e_phnum);
>  	NEW_AUX_ENT(AT_BASE,	interp_params->elfhdr_addr);
> -	NEW_AUX_ENT(AT_FLAGS,	0);
> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
> +	NEW_AUX_ENT(AT_FLAGS,	flags);
>  	NEW_AUX_ENT(AT_ENTRY,	exec_params->entry_addr);
>  	NEW_AUX_ENT(AT_UID,	(elf_addr_t) from_kuid_munged(cred-
> >user_ns, cred->uid));
>  	NEW_AUX_ENT(AT_EUID,	(elf_addr_t) from_kuid_munged(cred-
> >user_ns, cred->euid));
> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
> index cdb45829354d..b9acdd26a654 100644
> --- a/fs/binfmt_misc.c
> +++ b/fs/binfmt_misc.c
> @@ -154,7 +154,9 @@ static int load_misc_binary(struct linux_binprm
> *bprm)
>  	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
>  		goto ret;
>  
> -	if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
> +	if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
> +		bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
> +	} else {
>  		retval = remove_arg_zero(bprm);
>  		if (retval)
>  			goto ret;
> diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
> index b40fc633f3be..265b80d5fd6f 100644
> --- a/include/linux/binfmts.h
> +++ b/include/linux/binfmts.h
> @@ -78,6 +78,10 @@ struct linux_binprm {
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 <<
> BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
>  
> +/* if preserve the argv0 for the interpreter  */
> +#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
> +#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 <<
> BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  /* Function parameter for binfmt->coredump */
>  struct coredump_params {
>  	const kernel_siginfo_t *siginfo;
> diff --git a/include/uapi/linux/binfmts.h
> b/include/uapi/linux/binfmts.h
> index 689025d9c185..a70747416130 100644
> --- a/include/uapi/linux/binfmts.h
> +++ b/include/uapi/linux/binfmts.h
> @@ -18,4 +18,8 @@ struct pt_regs;
>  /* sizeof(linux_binprm->buf) */
>  #define BINPRM_BUF_SIZE 256
>  
> +/* if preserve the argv0 for the interpreter  */
> +#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
> +#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  #endif /* _UAPI_LINUX_BINFMTS_H */


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter
  2020-01-28 13:25 [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter Laurent Vivier
  2020-02-02 12:15 ` [EXTERNAL][PATCH " YunQiang Su
@ 2020-02-14 12:29 ` Laurent Vivier
  2020-02-20 10:07   ` Laurent Vivier
  2020-02-27  7:27 ` YunQiang Su
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Laurent Vivier @ 2020-02-14 12:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fsdevel, YunQiang Su, YunQiang Su, Alexander Viro, James Bottomley

Hi,

any comment?

I think I've addressed comments on v2.

Thanks,
Laurent

Le 28/01/2020 à 14:25, Laurent Vivier a écrit :
> 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.
> 
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> 
> Notes:
>     This can be tested with QEMU from my branch:
>     
>       https://github.com/vivier/qemu/commits/binfmt-argv0
>     
>     With something like:
>     
>       # cp ..../qemu-ppc /chroot/powerpc/jessie
>     
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>                             --persistent no --preserve-argv0 yes
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: POC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       sh
>     
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>                             --persistent no --preserve-argv0 no
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: OC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       /bin/sh
>     
>     v3: mix my patch with one from YunQiang Su and my comments on it
>         introduce a new flag in the uabi for the AT_FLAGS
>     v2: only pass special flags (remove Magic and Enabled flags)
> 
>  fs/binfmt_elf.c              | 5 ++++-
>  fs/binfmt_elf_fdpic.c        | 5 ++++-
>  fs/binfmt_misc.c             | 4 +++-
>  include/linux/binfmts.h      | 4 ++++
>  include/uapi/linux/binfmts.h | 4 ++++
>  5 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index ecd8d2698515..ff918042ceed 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -176,6 +176,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>  	unsigned char k_rand_bytes[16];
>  	int items;
>  	elf_addr_t *elf_info;
> +	elf_addr_t flags = 0;
>  	int ei_index = 0;
>  	const struct cred *cred = current_cred();
>  	struct vm_area_struct *vma;
> @@ -250,7 +251,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>  	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
>  	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
>  	NEW_AUX_ENT(AT_BASE, interp_load_addr);
> -	NEW_AUX_ENT(AT_FLAGS, 0);
> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
> +	NEW_AUX_ENT(AT_FLAGS, flags);
>  	NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
>  	NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
>  	NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
> index 240f66663543..abb90d82aa58 100644
> --- a/fs/binfmt_elf_fdpic.c
> +++ b/fs/binfmt_elf_fdpic.c
> @@ -507,6 +507,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>  	char __user *u_platform, *u_base_platform, *p;
>  	int loop;
>  	int nr;	/* reset for each csp adjustment */
> +	unsigned long flags = 0;
>  
>  #ifdef CONFIG_MMU
>  	/* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
> @@ -647,7 +648,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>  	NEW_AUX_ENT(AT_PHENT,	sizeof(struct elf_phdr));
>  	NEW_AUX_ENT(AT_PHNUM,	exec_params->hdr.e_phnum);
>  	NEW_AUX_ENT(AT_BASE,	interp_params->elfhdr_addr);
> -	NEW_AUX_ENT(AT_FLAGS,	0);
> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
> +	NEW_AUX_ENT(AT_FLAGS,	flags);
>  	NEW_AUX_ENT(AT_ENTRY,	exec_params->entry_addr);
>  	NEW_AUX_ENT(AT_UID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->uid));
>  	NEW_AUX_ENT(AT_EUID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid));
> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
> index cdb45829354d..b9acdd26a654 100644
> --- a/fs/binfmt_misc.c
> +++ b/fs/binfmt_misc.c
> @@ -154,7 +154,9 @@ static int load_misc_binary(struct linux_binprm *bprm)
>  	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
>  		goto ret;
>  
> -	if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
> +	if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
> +		bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
> +	} else {
>  		retval = remove_arg_zero(bprm);
>  		if (retval)
>  			goto ret;
> diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
> index b40fc633f3be..265b80d5fd6f 100644
> --- a/include/linux/binfmts.h
> +++ b/include/linux/binfmts.h
> @@ -78,6 +78,10 @@ struct linux_binprm {
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
>  
> +/* if preserve the argv0 for the interpreter  */
> +#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
> +#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  /* Function parameter for binfmt->coredump */
>  struct coredump_params {
>  	const kernel_siginfo_t *siginfo;
> diff --git a/include/uapi/linux/binfmts.h b/include/uapi/linux/binfmts.h
> index 689025d9c185..a70747416130 100644
> --- a/include/uapi/linux/binfmts.h
> +++ b/include/uapi/linux/binfmts.h
> @@ -18,4 +18,8 @@ struct pt_regs;
>  /* sizeof(linux_binprm->buf) */
>  #define BINPRM_BUF_SIZE 256
>  
> +/* if preserve the argv0 for the interpreter  */
> +#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
> +#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  #endif /* _UAPI_LINUX_BINFMTS_H */
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter
  2020-02-14 12:29 ` [PATCH " Laurent Vivier
@ 2020-02-20 10:07   ` Laurent Vivier
  0 siblings, 0 replies; 9+ messages in thread
From: Laurent Vivier @ 2020-02-20 10:07 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fsdevel, YunQiang Su, YunQiang Su, Alexander Viro, James Bottomley

I'd like to have this in the kernel to be able to use it in QEMU (next
QEMU release is 28/04, freeze 17/03).

Thanks,
Laurent

Le 14/02/2020 à 13:29, Laurent Vivier a écrit :
> Hi,
> 
> any comment?
> 
> I think I've addressed comments on v2.
> 
> Thanks,
> Laurent
> 
> Le 28/01/2020 à 14:25, Laurent Vivier a écrit :
>> 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.
>>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>> ---
>>
>> Notes:
>>     This can be tested with QEMU from my branch:
>>     
>>       https://github.com/vivier/qemu/commits/binfmt-argv0
>>     
>>     With something like:
>>     
>>       # cp ..../qemu-ppc /chroot/powerpc/jessie
>>     
>>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>>                             --persistent no --preserve-argv0 yes
>>       # systemctl restart systemd-binfmt.service
>>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>>       enabled
>>       interpreter //qemu-ppc
>>       flags: POC
>>       offset 0
>>       magic 7f454c4601020100000000000000000000020014
>>       mask ffffffffffffff00fffffffffffffffffffeffff
>>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>>       sh
>>     
>>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>>                             --persistent no --preserve-argv0 no
>>       # systemctl restart systemd-binfmt.service
>>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>>       enabled
>>       interpreter //qemu-ppc
>>       flags: OC
>>       offset 0
>>       magic 7f454c4601020100000000000000000000020014
>>       mask ffffffffffffff00fffffffffffffffffffeffff
>>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>>       /bin/sh
>>     
>>     v3: mix my patch with one from YunQiang Su and my comments on it
>>         introduce a new flag in the uabi for the AT_FLAGS
>>     v2: only pass special flags (remove Magic and Enabled flags)
>>
>>  fs/binfmt_elf.c              | 5 ++++-
>>  fs/binfmt_elf_fdpic.c        | 5 ++++-
>>  fs/binfmt_misc.c             | 4 +++-
>>  include/linux/binfmts.h      | 4 ++++
>>  include/uapi/linux/binfmts.h | 4 ++++
>>  5 files changed, 19 insertions(+), 3 deletions(-)
>>
>> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
>> index ecd8d2698515..ff918042ceed 100644
>> --- a/fs/binfmt_elf.c
>> +++ b/fs/binfmt_elf.c
>> @@ -176,6 +176,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>>  	unsigned char k_rand_bytes[16];
>>  	int items;
>>  	elf_addr_t *elf_info;
>> +	elf_addr_t flags = 0;
>>  	int ei_index = 0;
>>  	const struct cred *cred = current_cred();
>>  	struct vm_area_struct *vma;
>> @@ -250,7 +251,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>>  	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
>>  	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
>>  	NEW_AUX_ENT(AT_BASE, interp_load_addr);
>> -	NEW_AUX_ENT(AT_FLAGS, 0);
>> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
>> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
>> +	NEW_AUX_ENT(AT_FLAGS, flags);
>>  	NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
>>  	NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
>>  	NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
>> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
>> index 240f66663543..abb90d82aa58 100644
>> --- a/fs/binfmt_elf_fdpic.c
>> +++ b/fs/binfmt_elf_fdpic.c
>> @@ -507,6 +507,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>>  	char __user *u_platform, *u_base_platform, *p;
>>  	int loop;
>>  	int nr;	/* reset for each csp adjustment */
>> +	unsigned long flags = 0;
>>  
>>  #ifdef CONFIG_MMU
>>  	/* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
>> @@ -647,7 +648,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>>  	NEW_AUX_ENT(AT_PHENT,	sizeof(struct elf_phdr));
>>  	NEW_AUX_ENT(AT_PHNUM,	exec_params->hdr.e_phnum);
>>  	NEW_AUX_ENT(AT_BASE,	interp_params->elfhdr_addr);
>> -	NEW_AUX_ENT(AT_FLAGS,	0);
>> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
>> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
>> +	NEW_AUX_ENT(AT_FLAGS,	flags);
>>  	NEW_AUX_ENT(AT_ENTRY,	exec_params->entry_addr);
>>  	NEW_AUX_ENT(AT_UID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->uid));
>>  	NEW_AUX_ENT(AT_EUID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid));
>> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
>> index cdb45829354d..b9acdd26a654 100644
>> --- a/fs/binfmt_misc.c
>> +++ b/fs/binfmt_misc.c
>> @@ -154,7 +154,9 @@ static int load_misc_binary(struct linux_binprm *bprm)
>>  	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
>>  		goto ret;
>>  
>> -	if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
>> +	if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
>> +		bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
>> +	} else {
>>  		retval = remove_arg_zero(bprm);
>>  		if (retval)
>>  			goto ret;
>> diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
>> index b40fc633f3be..265b80d5fd6f 100644
>> --- a/include/linux/binfmts.h
>> +++ b/include/linux/binfmts.h
>> @@ -78,6 +78,10 @@ struct linux_binprm {
>>  #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
>>  #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
>>  
>> +/* if preserve the argv0 for the interpreter  */
>> +#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
>> +#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
>> +
>>  /* Function parameter for binfmt->coredump */
>>  struct coredump_params {
>>  	const kernel_siginfo_t *siginfo;
>> diff --git a/include/uapi/linux/binfmts.h b/include/uapi/linux/binfmts.h
>> index 689025d9c185..a70747416130 100644
>> --- a/include/uapi/linux/binfmts.h
>> +++ b/include/uapi/linux/binfmts.h
>> @@ -18,4 +18,8 @@ struct pt_regs;
>>  /* sizeof(linux_binprm->buf) */
>>  #define BINPRM_BUF_SIZE 256
>>  
>> +/* if preserve the argv0 for the interpreter  */
>> +#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
>> +#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
>> +
>>  #endif /* _UAPI_LINUX_BINFMTS_H */
>>
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter
  2020-01-28 13:25 [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter Laurent Vivier
  2020-02-02 12:15 ` [EXTERNAL][PATCH " YunQiang Su
  2020-02-14 12:29 ` [PATCH " Laurent Vivier
@ 2020-02-27  7:27 ` YunQiang Su
  2020-03-01  0:47 ` YunQiang Su
  2020-06-05 16:20 ` Laurent Vivier
  4 siblings, 0 replies; 9+ messages in thread
From: YunQiang Su @ 2020-02-27  7:27 UTC (permalink / raw)
  To: Laurent Vivier, linux-kernel
  Cc: linux-fsdevel, Alexander Viro, James Bottomley, libc-alpha

[-- Attachment #1: Type: text/plain, Size: 6201 bytes --]

在 2020-01-28二的 14:25 +0100,Laurent Vivier写道:
> 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.

CC: libc-alpha.
I guess we need some review from libc people.

> 
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> 
> Notes:
>     This can be tested with QEMU from my branch:
>     
>       https://github.com/vivier/qemu/commits/binfmt-argv0
>     
>     With something like:
>     
>       # cp ..../qemu-ppc /chroot/powerpc/jessie
>     
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential
> yes \
>                             --persistent no --preserve-argv0 yes
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: POC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       sh
>     
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential
> yes \
>                             --persistent no --preserve-argv0 no
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: OC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       /bin/sh
>     
>     v3: mix my patch with one from YunQiang Su and my comments on it
>         introduce a new flag in the uabi for the AT_FLAGS
>     v2: only pass special flags (remove Magic and Enabled flags)
> 
>  fs/binfmt_elf.c              | 5 ++++-
>  fs/binfmt_elf_fdpic.c        | 5 ++++-
>  fs/binfmt_misc.c             | 4 +++-
>  include/linux/binfmts.h      | 4 ++++
>  include/uapi/linux/binfmts.h | 4 ++++
>  5 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index ecd8d2698515..ff918042ceed 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -176,6 +176,7 @@ create_elf_tables(struct linux_binprm *bprm,
> struct elfhdr *exec,
>  	unsigned char k_rand_bytes[16];
>  	int items;
>  	elf_addr_t *elf_info;
> +	elf_addr_t flags = 0;
>  	int ei_index = 0;
>  	const struct cred *cred = current_cred();
>  	struct vm_area_struct *vma;
> @@ -250,7 +251,9 @@ create_elf_tables(struct linux_binprm *bprm,
> struct elfhdr *exec,
>  	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
>  	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
>  	NEW_AUX_ENT(AT_BASE, interp_load_addr);
> -	NEW_AUX_ENT(AT_FLAGS, 0);
> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
> +	NEW_AUX_ENT(AT_FLAGS, flags);
>  	NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
>  	NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred-
> >uid));
>  	NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred-
> >euid));
> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
> index 240f66663543..abb90d82aa58 100644
> --- a/fs/binfmt_elf_fdpic.c
> +++ b/fs/binfmt_elf_fdpic.c
> @@ -507,6 +507,7 @@ static int create_elf_fdpic_tables(struct
> linux_binprm *bprm,
>  	char __user *u_platform, *u_base_platform, *p;
>  	int loop;
>  	int nr;	/* reset for each csp adjustment */
> +	unsigned long flags = 0;
>  
>  #ifdef CONFIG_MMU
>  	/* In some cases (e.g. Hyper-Threading), we want to avoid L1
> evictions
> @@ -647,7 +648,9 @@ static int create_elf_fdpic_tables(struct
> linux_binprm *bprm,
>  	NEW_AUX_ENT(AT_PHENT,	sizeof(struct elf_phdr));
>  	NEW_AUX_ENT(AT_PHNUM,	exec_params->hdr.e_phnum);
>  	NEW_AUX_ENT(AT_BASE,	interp_params->elfhdr_addr);
> -	NEW_AUX_ENT(AT_FLAGS,	0);
> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
> +	NEW_AUX_ENT(AT_FLAGS,	flags);
>  	NEW_AUX_ENT(AT_ENTRY,	exec_params->entry_addr);
>  	NEW_AUX_ENT(AT_UID,	(elf_addr_t) from_kuid_munged(cred-
> >user_ns, cred->uid));
>  	NEW_AUX_ENT(AT_EUID,	(elf_addr_t) from_kuid_munged(cred-
> >user_ns, cred->euid));
> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
> index cdb45829354d..b9acdd26a654 100644
> --- a/fs/binfmt_misc.c
> +++ b/fs/binfmt_misc.c
> @@ -154,7 +154,9 @@ static int load_misc_binary(struct linux_binprm
> *bprm)
>  	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
>  		goto ret;
>  
> -	if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
> +	if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
> +		bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
> +	} else {
>  		retval = remove_arg_zero(bprm);
>  		if (retval)
>  			goto ret;
> diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
> index b40fc633f3be..265b80d5fd6f 100644
> --- a/include/linux/binfmts.h
> +++ b/include/linux/binfmts.h
> @@ -78,6 +78,10 @@ struct linux_binprm {
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 <<
> BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
>  
> +/* if preserve the argv0 for the interpreter  */
> +#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
> +#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 <<
> BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  /* Function parameter for binfmt->coredump */
>  struct coredump_params {
>  	const kernel_siginfo_t *siginfo;
> diff --git a/include/uapi/linux/binfmts.h
> b/include/uapi/linux/binfmts.h
> index 689025d9c185..a70747416130 100644
> --- a/include/uapi/linux/binfmts.h
> +++ b/include/uapi/linux/binfmts.h
> @@ -18,4 +18,8 @@ struct pt_regs;
>  /* sizeof(linux_binprm->buf) */
>  #define BINPRM_BUF_SIZE 256
>  
> +/* if preserve the argv0 for the interpreter  */
> +#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
> +#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  #endif /* _UAPI_LINUX_BINFMTS_H */

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter
  2020-01-28 13:25 [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter Laurent Vivier
                   ` (2 preceding siblings ...)
  2020-02-27  7:27 ` YunQiang Su
@ 2020-03-01  0:47 ` YunQiang Su
  2020-06-05 16:20 ` Laurent Vivier
  4 siblings, 0 replies; 9+ messages in thread
From: YunQiang Su @ 2020-03-01  0:47 UTC (permalink / raw)
  To: Laurent Vivier
  Cc: linux-kernel, linux-fsdevel, Alexander Viro, James Bottomley,
	libc-alpha, linux-arch, linux-api

Laurent Vivier <laurent@vivier.eu> 于2020年1月28日周二 下午9:25写道:
>
> 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.
>

I am suggested to post linux-arch and/or linux-api.

> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>
> Notes:
>     This can be tested with QEMU from my branch:
>
>       https://github.com/vivier/qemu/commits/binfmt-argv0
>
>     With something like:
>
>       # cp ..../qemu-ppc /chroot/powerpc/jessie
>
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>                             --persistent no --preserve-argv0 yes
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: POC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       sh
>
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>                             --persistent no --preserve-argv0 no
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: OC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       /bin/sh
>
>     v3: mix my patch with one from YunQiang Su and my comments on it
>         introduce a new flag in the uabi for the AT_FLAGS
>     v2: only pass special flags (remove Magic and Enabled flags)
>
>  fs/binfmt_elf.c              | 5 ++++-
>  fs/binfmt_elf_fdpic.c        | 5 ++++-
>  fs/binfmt_misc.c             | 4 +++-
>  include/linux/binfmts.h      | 4 ++++
>  include/uapi/linux/binfmts.h | 4 ++++
>  5 files changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index ecd8d2698515..ff918042ceed 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -176,6 +176,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>         unsigned char k_rand_bytes[16];
>         int items;
>         elf_addr_t *elf_info;
> +       elf_addr_t flags = 0;
>         int ei_index = 0;
>         const struct cred *cred = current_cred();
>         struct vm_area_struct *vma;
> @@ -250,7 +251,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>         NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
>         NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
>         NEW_AUX_ENT(AT_BASE, interp_load_addr);
> -       NEW_AUX_ENT(AT_FLAGS, 0);
> +       if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +               flags |= AT_FLAGS_PRESERVE_ARGV0;
> +       NEW_AUX_ENT(AT_FLAGS, flags);
>         NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
>         NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
>         NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
> index 240f66663543..abb90d82aa58 100644
> --- a/fs/binfmt_elf_fdpic.c
> +++ b/fs/binfmt_elf_fdpic.c
> @@ -507,6 +507,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>         char __user *u_platform, *u_base_platform, *p;
>         int loop;
>         int nr; /* reset for each csp adjustment */
> +       unsigned long flags = 0;
>
>  #ifdef CONFIG_MMU
>         /* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
> @@ -647,7 +648,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>         NEW_AUX_ENT(AT_PHENT,   sizeof(struct elf_phdr));
>         NEW_AUX_ENT(AT_PHNUM,   exec_params->hdr.e_phnum);
>         NEW_AUX_ENT(AT_BASE,    interp_params->elfhdr_addr);
> -       NEW_AUX_ENT(AT_FLAGS,   0);
> +       if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +               flags |= AT_FLAGS_PRESERVE_ARGV0;
> +       NEW_AUX_ENT(AT_FLAGS,   flags);
>         NEW_AUX_ENT(AT_ENTRY,   exec_params->entry_addr);
>         NEW_AUX_ENT(AT_UID,     (elf_addr_t) from_kuid_munged(cred->user_ns, cred->uid));
>         NEW_AUX_ENT(AT_EUID,    (elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid));
> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
> index cdb45829354d..b9acdd26a654 100644
> --- a/fs/binfmt_misc.c
> +++ b/fs/binfmt_misc.c
> @@ -154,7 +154,9 @@ static int load_misc_binary(struct linux_binprm *bprm)
>         if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
>                 goto ret;
>
> -       if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
> +       if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
> +               bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
> +       } else {
>                 retval = remove_arg_zero(bprm);
>                 if (retval)
>                         goto ret;
> diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
> index b40fc633f3be..265b80d5fd6f 100644
> --- a/include/linux/binfmts.h
> +++ b/include/linux/binfmts.h
> @@ -78,6 +78,10 @@ struct linux_binprm {
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
>
> +/* if preserve the argv0 for the interpreter  */
> +#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
> +#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  /* Function parameter for binfmt->coredump */
>  struct coredump_params {
>         const kernel_siginfo_t *siginfo;
> diff --git a/include/uapi/linux/binfmts.h b/include/uapi/linux/binfmts.h
> index 689025d9c185..a70747416130 100644
> --- a/include/uapi/linux/binfmts.h
> +++ b/include/uapi/linux/binfmts.h
> @@ -18,4 +18,8 @@ struct pt_regs;
>  /* sizeof(linux_binprm->buf) */
>  #define BINPRM_BUF_SIZE 256
>
> +/* if preserve the argv0 for the interpreter  */
> +#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
> +#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  #endif /* _UAPI_LINUX_BINFMTS_H */
> --
> 2.24.1
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter
  2020-01-28 13:25 [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter Laurent Vivier
                   ` (3 preceding siblings ...)
  2020-03-01  0:47 ` YunQiang Su
@ 2020-06-05 16:20 ` Laurent Vivier
  2021-02-13  7:40   ` Helge Deller
  4 siblings, 1 reply; 9+ messages in thread
From: Laurent Vivier @ 2020-06-05 16:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fsdevel, YunQiang Su, YunQiang Su, Alexander Viro, James Bottomley

Ping?

Thanks,
Laurent

Le 28/01/2020 à 14:25, Laurent Vivier a écrit :
> 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.
> 
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> 
> Notes:
>     This can be tested with QEMU from my branch:
>     
>       https://github.com/vivier/qemu/commits/binfmt-argv0
>     
>     With something like:
>     
>       # cp ..../qemu-ppc /chroot/powerpc/jessie
>     
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>                             --persistent no --preserve-argv0 yes
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: POC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       sh
>     
>       # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>                             --persistent no --preserve-argv0 no
>       # systemctl restart systemd-binfmt.service
>       # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>       enabled
>       interpreter //qemu-ppc
>       flags: OC
>       offset 0
>       magic 7f454c4601020100000000000000000000020014
>       mask ffffffffffffff00fffffffffffffffffffeffff
>       # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>       /bin/sh
>     
>     v3: mix my patch with one from YunQiang Su and my comments on it
>         introduce a new flag in the uabi for the AT_FLAGS
>     v2: only pass special flags (remove Magic and Enabled flags)
> 
>  fs/binfmt_elf.c              | 5 ++++-
>  fs/binfmt_elf_fdpic.c        | 5 ++++-
>  fs/binfmt_misc.c             | 4 +++-
>  include/linux/binfmts.h      | 4 ++++
>  include/uapi/linux/binfmts.h | 4 ++++
>  5 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index ecd8d2698515..ff918042ceed 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -176,6 +176,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>  	unsigned char k_rand_bytes[16];
>  	int items;
>  	elf_addr_t *elf_info;
> +	elf_addr_t flags = 0;
>  	int ei_index = 0;
>  	const struct cred *cred = current_cred();
>  	struct vm_area_struct *vma;
> @@ -250,7 +251,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>  	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
>  	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
>  	NEW_AUX_ENT(AT_BASE, interp_load_addr);
> -	NEW_AUX_ENT(AT_FLAGS, 0);
> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
> +	NEW_AUX_ENT(AT_FLAGS, flags);
>  	NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
>  	NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
>  	NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
> index 240f66663543..abb90d82aa58 100644
> --- a/fs/binfmt_elf_fdpic.c
> +++ b/fs/binfmt_elf_fdpic.c
> @@ -507,6 +507,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>  	char __user *u_platform, *u_base_platform, *p;
>  	int loop;
>  	int nr;	/* reset for each csp adjustment */
> +	unsigned long flags = 0;
>  
>  #ifdef CONFIG_MMU
>  	/* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
> @@ -647,7 +648,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>  	NEW_AUX_ENT(AT_PHENT,	sizeof(struct elf_phdr));
>  	NEW_AUX_ENT(AT_PHNUM,	exec_params->hdr.e_phnum);
>  	NEW_AUX_ENT(AT_BASE,	interp_params->elfhdr_addr);
> -	NEW_AUX_ENT(AT_FLAGS,	0);
> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
> +	NEW_AUX_ENT(AT_FLAGS,	flags);
>  	NEW_AUX_ENT(AT_ENTRY,	exec_params->entry_addr);
>  	NEW_AUX_ENT(AT_UID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->uid));
>  	NEW_AUX_ENT(AT_EUID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid));
> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
> index cdb45829354d..b9acdd26a654 100644
> --- a/fs/binfmt_misc.c
> +++ b/fs/binfmt_misc.c
> @@ -154,7 +154,9 @@ static int load_misc_binary(struct linux_binprm *bprm)
>  	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
>  		goto ret;
>  
> -	if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
> +	if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
> +		bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
> +	} else {
>  		retval = remove_arg_zero(bprm);
>  		if (retval)
>  			goto ret;
> diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
> index b40fc633f3be..265b80d5fd6f 100644
> --- a/include/linux/binfmts.h
> +++ b/include/linux/binfmts.h
> @@ -78,6 +78,10 @@ struct linux_binprm {
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
>  #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
>  
> +/* if preserve the argv0 for the interpreter  */
> +#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
> +#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  /* Function parameter for binfmt->coredump */
>  struct coredump_params {
>  	const kernel_siginfo_t *siginfo;
> diff --git a/include/uapi/linux/binfmts.h b/include/uapi/linux/binfmts.h
> index 689025d9c185..a70747416130 100644
> --- a/include/uapi/linux/binfmts.h
> +++ b/include/uapi/linux/binfmts.h
> @@ -18,4 +18,8 @@ struct pt_regs;
>  /* sizeof(linux_binprm->buf) */
>  #define BINPRM_BUF_SIZE 256
>  
> +/* if preserve the argv0 for the interpreter  */
> +#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
> +#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
> +
>  #endif /* _UAPI_LINUX_BINFMTS_H */
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter
  2020-06-05 16:20 ` Laurent Vivier
@ 2021-02-13  7:40   ` Helge Deller
  2021-02-23  5:35     ` YunQiang Su
  0 siblings, 1 reply; 9+ messages in thread
From: Helge Deller @ 2021-02-13  7:40 UTC (permalink / raw)
  To: Laurent Vivier, linux-kernel
  Cc: linux-fsdevel, YunQiang Su, YunQiang Su, Alexander Viro, James Bottomley

On 6/5/20 6:20 PM, Laurent Vivier wrote:
> Le 28/01/2020 à 14:25, Laurent Vivier a écrit :
>> 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.
>>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>

Acked-by: Helge Deller <deller@gmx.de>

If nobody objects, I'd like to take this patch through the
parisc arch git tree.

It fixes a real-world problem with qemu-user which fails to
preserve the argv[0] argument when the callee of an exec is a
qemu-user target.
This problem leads to build errors on multiple Debian buildd servers
which are using qemu-user as emulation for the target machines.

For details see Debian bug:
http://bugs.debian.org/970460


Helge


>> ---
>>
>> Notes:
>>      This can be tested with QEMU from my branch:
>>
>>        https://github.com/vivier/qemu/commits/binfmt-argv0
>>
>>      With something like:
>>
>>        # cp ..../qemu-ppc /chroot/powerpc/jessie
>>
>>        # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>>                              --persistent no --preserve-argv0 yes
>>        # systemctl restart systemd-binfmt.service
>>        # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>>        enabled
>>        interpreter //qemu-ppc
>>        flags: POC
>>        offset 0
>>        magic 7f454c4601020100000000000000000000020014
>>        mask ffffffffffffff00fffffffffffffffffffeffff
>>        # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>>        sh
>>
>>        # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
>>                              --persistent no --preserve-argv0 no
>>        # systemctl restart systemd-binfmt.service
>>        # cat /proc/sys/fs/binfmt_misc/qemu-ppc
>>        enabled
>>        interpreter //qemu-ppc
>>        flags: OC
>>        offset 0
>>        magic 7f454c4601020100000000000000000000020014
>>        mask ffffffffffffff00fffffffffffffffffffeffff
>>        # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
>>        /bin/sh
>>
>>      v3: mix my patch with one from YunQiang Su and my comments on it
>>          introduce a new flag in the uabi for the AT_FLAGS
>>      v2: only pass special flags (remove Magic and Enabled flags)
>>
>>   fs/binfmt_elf.c              | 5 ++++-
>>   fs/binfmt_elf_fdpic.c        | 5 ++++-
>>   fs/binfmt_misc.c             | 4 +++-
>>   include/linux/binfmts.h      | 4 ++++
>>   include/uapi/linux/binfmts.h | 4 ++++
>>   5 files changed, 19 insertions(+), 3 deletions(-)
>>
>> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
>> index ecd8d2698515..ff918042ceed 100644
>> --- a/fs/binfmt_elf.c
>> +++ b/fs/binfmt_elf.c
>> @@ -176,6 +176,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>>   	unsigned char k_rand_bytes[16];
>>   	int items;
>>   	elf_addr_t *elf_info;
>> +	elf_addr_t flags = 0;
>>   	int ei_index = 0;
>>   	const struct cred *cred = current_cred();
>>   	struct vm_area_struct *vma;
>> @@ -250,7 +251,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
>>   	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
>>   	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
>>   	NEW_AUX_ENT(AT_BASE, interp_load_addr);
>> -	NEW_AUX_ENT(AT_FLAGS, 0);
>> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
>> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
>> +	NEW_AUX_ENT(AT_FLAGS, flags);
>>   	NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
>>   	NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
>>   	NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
>> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
>> index 240f66663543..abb90d82aa58 100644
>> --- a/fs/binfmt_elf_fdpic.c
>> +++ b/fs/binfmt_elf_fdpic.c
>> @@ -507,6 +507,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>>   	char __user *u_platform, *u_base_platform, *p;
>>   	int loop;
>>   	int nr;	/* reset for each csp adjustment */
>> +	unsigned long flags = 0;
>>
>>   #ifdef CONFIG_MMU
>>   	/* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
>> @@ -647,7 +648,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
>>   	NEW_AUX_ENT(AT_PHENT,	sizeof(struct elf_phdr));
>>   	NEW_AUX_ENT(AT_PHNUM,	exec_params->hdr.e_phnum);
>>   	NEW_AUX_ENT(AT_BASE,	interp_params->elfhdr_addr);
>> -	NEW_AUX_ENT(AT_FLAGS,	0);
>> +	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
>> +		flags |= AT_FLAGS_PRESERVE_ARGV0;
>> +	NEW_AUX_ENT(AT_FLAGS,	flags);
>>   	NEW_AUX_ENT(AT_ENTRY,	exec_params->entry_addr);
>>   	NEW_AUX_ENT(AT_UID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->uid));
>>   	NEW_AUX_ENT(AT_EUID,	(elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid));
>> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
>> index cdb45829354d..b9acdd26a654 100644
>> --- a/fs/binfmt_misc.c
>> +++ b/fs/binfmt_misc.c
>> @@ -154,7 +154,9 @@ static int load_misc_binary(struct linux_binprm *bprm)
>>   	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
>>   		goto ret;
>>
>> -	if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
>> +	if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
>> +		bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
>> +	} else {
>>   		retval = remove_arg_zero(bprm);
>>   		if (retval)
>>   			goto ret;
>> diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
>> index b40fc633f3be..265b80d5fd6f 100644
>> --- a/include/linux/binfmts.h
>> +++ b/include/linux/binfmts.h
>> @@ -78,6 +78,10 @@ struct linux_binprm {
>>   #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
>>   #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
>>
>> +/* if preserve the argv0 for the interpreter  */
>> +#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
>> +#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
>> +
>>   /* Function parameter for binfmt->coredump */
>>   struct coredump_params {
>>   	const kernel_siginfo_t *siginfo;
>> diff --git a/include/uapi/linux/binfmts.h b/include/uapi/linux/binfmts.h
>> index 689025d9c185..a70747416130 100644
>> --- a/include/uapi/linux/binfmts.h
>> +++ b/include/uapi/linux/binfmts.h
>> @@ -18,4 +18,8 @@ struct pt_regs;
>>   /* sizeof(linux_binprm->buf) */
>>   #define BINPRM_BUF_SIZE 256
>>
>> +/* if preserve the argv0 for the interpreter  */
>> +#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
>> +#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
>> +
>>   #endif /* _UAPI_LINUX_BINFMTS_H */
>>
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter
  2021-02-13  7:40   ` Helge Deller
@ 2021-02-23  5:35     ` YunQiang Su
  0 siblings, 0 replies; 9+ messages in thread
From: YunQiang Su @ 2021-02-23  5:35 UTC (permalink / raw)
  To: Helge Deller
  Cc: Laurent Vivier, LKML, linux-fsdevel, YunQiang Su, Alexander Viro,
	James Bottomley

Helge Deller <deller@gmx.de> 于2021年2月13日周六 下午3:40写道:
>
> On 6/5/20 6:20 PM, Laurent Vivier wrote:
> > Le 28/01/2020 à 14:25, Laurent Vivier a écrit :
> >> 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.
> >>
> >> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>
> Acked-by: Helge Deller <deller@gmx.de>
>
> If nobody objects, I'd like to take this patch through the
> parisc arch git tree.
>

Thank you. I see this patch has been in linux-next now.
@Laurent, I guess it is time to work on to push the patch for qemu?

> It fixes a real-world problem with qemu-user which fails to
> preserve the argv[0] argument when the callee of an exec is a
> qemu-user target.
> This problem leads to build errors on multiple Debian buildd servers
> which are using qemu-user as emulation for the target machines.
>
> For details see Debian bug:
> http://bugs.debian.org/970460
>
>
> Helge
>
>
> >> ---
> >>
> >> Notes:
> >>      This can be tested with QEMU from my branch:
> >>
> >>        https://github.com/vivier/qemu/commits/binfmt-argv0
> >>
> >>      With something like:
> >>
> >>        # cp ..../qemu-ppc /chroot/powerpc/jessie
> >>
> >>        # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
> >>                              --persistent no --preserve-argv0 yes
> >>        # systemctl restart systemd-binfmt.service
> >>        # cat /proc/sys/fs/binfmt_misc/qemu-ppc
> >>        enabled
> >>        interpreter //qemu-ppc
> >>        flags: POC
> >>        offset 0
> >>        magic 7f454c4601020100000000000000000000020014
> >>        mask ffffffffffffff00fffffffffffffffffffeffff
> >>        # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
> >>        sh
> >>
> >>        # qemu-binfmt-conf.sh --qemu-path / --systemd ppc --credential yes \
> >>                              --persistent no --preserve-argv0 no
> >>        # systemctl restart systemd-binfmt.service
> >>        # cat /proc/sys/fs/binfmt_misc/qemu-ppc
> >>        enabled
> >>        interpreter //qemu-ppc
> >>        flags: OC
> >>        offset 0
> >>        magic 7f454c4601020100000000000000000000020014
> >>        mask ffffffffffffff00fffffffffffffffffffeffff
> >>        # chroot /chroot/powerpc/jessie  sh -c 'echo $0'
> >>        /bin/sh
> >>
> >>      v3: mix my patch with one from YunQiang Su and my comments on it
> >>          introduce a new flag in the uabi for the AT_FLAGS
> >>      v2: only pass special flags (remove Magic and Enabled flags)
> >>
> >>   fs/binfmt_elf.c              | 5 ++++-
> >>   fs/binfmt_elf_fdpic.c        | 5 ++++-
> >>   fs/binfmt_misc.c             | 4 +++-
> >>   include/linux/binfmts.h      | 4 ++++
> >>   include/uapi/linux/binfmts.h | 4 ++++
> >>   5 files changed, 19 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> >> index ecd8d2698515..ff918042ceed 100644
> >> --- a/fs/binfmt_elf.c
> >> +++ b/fs/binfmt_elf.c
> >> @@ -176,6 +176,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
> >>      unsigned char k_rand_bytes[16];
> >>      int items;
> >>      elf_addr_t *elf_info;
> >> +    elf_addr_t flags = 0;
> >>      int ei_index = 0;
> >>      const struct cred *cred = current_cred();
> >>      struct vm_area_struct *vma;
> >> @@ -250,7 +251,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
> >>      NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
> >>      NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
> >>      NEW_AUX_ENT(AT_BASE, interp_load_addr);
> >> -    NEW_AUX_ENT(AT_FLAGS, 0);
> >> +    if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> >> +            flags |= AT_FLAGS_PRESERVE_ARGV0;
> >> +    NEW_AUX_ENT(AT_FLAGS, flags);
> >>      NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
> >>      NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
> >>      NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
> >> diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
> >> index 240f66663543..abb90d82aa58 100644
> >> --- a/fs/binfmt_elf_fdpic.c
> >> +++ b/fs/binfmt_elf_fdpic.c
> >> @@ -507,6 +507,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
> >>      char __user *u_platform, *u_base_platform, *p;
> >>      int loop;
> >>      int nr; /* reset for each csp adjustment */
> >> +    unsigned long flags = 0;
> >>
> >>   #ifdef CONFIG_MMU
> >>      /* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
> >> @@ -647,7 +648,9 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
> >>      NEW_AUX_ENT(AT_PHENT,   sizeof(struct elf_phdr));
> >>      NEW_AUX_ENT(AT_PHNUM,   exec_params->hdr.e_phnum);
> >>      NEW_AUX_ENT(AT_BASE,    interp_params->elfhdr_addr);
> >> -    NEW_AUX_ENT(AT_FLAGS,   0);
> >> +    if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
> >> +            flags |= AT_FLAGS_PRESERVE_ARGV0;
> >> +    NEW_AUX_ENT(AT_FLAGS,   flags);
> >>      NEW_AUX_ENT(AT_ENTRY,   exec_params->entry_addr);
> >>      NEW_AUX_ENT(AT_UID,     (elf_addr_t) from_kuid_munged(cred->user_ns, cred->uid));
> >>      NEW_AUX_ENT(AT_EUID,    (elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid));
> >> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
> >> index cdb45829354d..b9acdd26a654 100644
> >> --- a/fs/binfmt_misc.c
> >> +++ b/fs/binfmt_misc.c
> >> @@ -154,7 +154,9 @@ static int load_misc_binary(struct linux_binprm *bprm)
> >>      if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
> >>              goto ret;
> >>
> >> -    if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
> >> +    if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
> >> +            bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
> >> +    } else {
> >>              retval = remove_arg_zero(bprm);
> >>              if (retval)
> >>                      goto ret;
> >> diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
> >> index b40fc633f3be..265b80d5fd6f 100644
> >> --- a/include/linux/binfmts.h
> >> +++ b/include/linux/binfmts.h
> >> @@ -78,6 +78,10 @@ struct linux_binprm {
> >>   #define BINPRM_FLAGS_PATH_INACCESSIBLE_BIT 2
> >>   #define BINPRM_FLAGS_PATH_INACCESSIBLE (1 << BINPRM_FLAGS_PATH_INACCESSIBLE_BIT)
> >>
> >> +/* if preserve the argv0 for the interpreter  */
> >> +#define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
> >> +#define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
> >> +
> >>   /* Function parameter for binfmt->coredump */
> >>   struct coredump_params {
> >>      const kernel_siginfo_t *siginfo;
> >> diff --git a/include/uapi/linux/binfmts.h b/include/uapi/linux/binfmts.h
> >> index 689025d9c185..a70747416130 100644
> >> --- a/include/uapi/linux/binfmts.h
> >> +++ b/include/uapi/linux/binfmts.h
> >> @@ -18,4 +18,8 @@ struct pt_regs;
> >>   /* sizeof(linux_binprm->buf) */
> >>   #define BINPRM_BUF_SIZE 256
> >>
> >> +/* if preserve the argv0 for the interpreter  */
> >> +#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
> >> +#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
> >> +
> >>   #endif /* _UAPI_LINUX_BINFMTS_H */
> >>
> >
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-02-23  5:34 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-28 13:25 [PATCH v3] binfmt_misc: pass binfmt_misc flags to the interpreter Laurent Vivier
2020-02-02 12:15 ` [EXTERNAL][PATCH " YunQiang Su
2020-02-14 12:29 ` [PATCH " Laurent Vivier
2020-02-20 10:07   ` Laurent Vivier
2020-02-27  7:27 ` YunQiang Su
2020-03-01  0:47 ` YunQiang Su
2020-06-05 16:20 ` Laurent Vivier
2021-02-13  7:40   ` Helge Deller
2021-02-23  5:35     ` YunQiang Su

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).