linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] [RFC] cross-arch: don't corrupt personality flags upon exec()
@ 2012-08-03 10:01 Jiri Kosina
  2012-08-13 13:19 ` Jiri Kosina
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Kosina @ 2012-08-03 10:01 UTC (permalink / raw)
  To: Haavard Skinnemoen, Hans-Christian Egtvedt, Mike Frysinger,
	Mark Salter, Mikael Starvik, Jesper Nilsson, David Howells,
	Yoshinori Sato, Richard Kuo, Hirokazu Takata, Geert Uytterhoeven,
	Michal Simek, Koichi Yasutake, Jonas Bonn, Chen Liqin, Lennox Wu,
	Paul Mundt, David S. Miller, Chris Zankel
  Cc: Andrew Morton, linux-kernel

Historically, the top three bytes of personality have been used for things 
such as ADDR_NO_RANDOMIZE, which made sense only for specific 
architectures.

We now, however, have a flag there that is general no matter the 
architecture (UNAME26); generally we have to be careful to preserve the 
personality flags across exec().

This patch tries to fix all architectures that forcefully overwrite
personality flags during exec() (ppc32 and s390 have been fixed recently 
by commits f9783ec86 and 59e4c3a2f in a similar way already).

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
---

Untested, as I don't own the hardware.

 arch/avr32/include/asm/elf.h      |    3 ++-
 arch/blackfin/include/asm/elf.h   |    3 ++-
 arch/c6x/include/asm/elf.h        |    3 ++-
 arch/cris/include/asm/elf.h       |    3 ++-
 arch/frv/include/asm/elf.h        |    3 ++-
 arch/h8300/include/asm/elf.h      |    3 ++-
 arch/hexagon/include/asm/elf.h    |    3 ++-
 arch/m32r/include/asm/elf.h       |    3 ++-
 arch/m68k/include/asm/elf.h       |    3 ++-
 arch/microblaze/include/asm/elf.h |    3 ++-
 arch/mn10300/include/asm/elf.h    |    3 ++-
 arch/openrisc/include/asm/elf.h   |    3 ++-
 arch/score/include/asm/elf.h      |    2 +-
 arch/sh/include/asm/elf.h         |    3 ++-
 arch/sparc/include/asm/elf_32.h   |    3 ++-
 arch/xtensa/include/asm/elf.h     |    3 ++-
 16 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h
index 3b3159b..e2c3287 100644
--- a/arch/avr32/include/asm/elf.h
+++ b/arch/avr32/include/asm/elf.h
@@ -102,6 +102,7 @@ typedef struct user_fpu_struct elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
 
 #endif /* __ASM_AVR32_ELF_H */
diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index e6c6812..14bc98f 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -132,6 +132,7 @@ do {											\
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 
 #endif
diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h
index f4552db..32b9971 100644
--- a/arch/c6x/include/asm/elf.h
+++ b/arch/c6x/include/asm/elf.h
@@ -77,7 +77,8 @@ do {								\
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 
 /* C6X specific section types */
 #define SHT_C6000_UNWIND	0x70000001
diff --git a/arch/cris/include/asm/elf.h b/arch/cris/include/asm/elf.h
index 8a3d8e2..8182f2d 100644
--- a/arch/cris/include/asm/elf.h
+++ b/arch/cris/include/asm/elf.h
@@ -86,6 +86,7 @@ typedef unsigned long elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 
 #endif
diff --git a/arch/frv/include/asm/elf.h b/arch/frv/include/asm/elf.h
index c381980..9ccbc80 100644
--- a/arch/frv/include/asm/elf.h
+++ b/arch/frv/include/asm/elf.h
@@ -137,6 +137,7 @@ do {											\
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 
 #endif
diff --git a/arch/h8300/include/asm/elf.h b/arch/h8300/include/asm/elf.h
index c24fa25..41193c3 100644
--- a/arch/h8300/include/asm/elf.h
+++ b/arch/h8300/include/asm/elf.h
@@ -54,7 +54,8 @@ typedef unsigned long elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 
 #define R_H8_NONE       0
 #define R_H8_DIR32      1
diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h
index 37976a0..82b4996 100644
--- a/arch/hexagon/include/asm/elf.h
+++ b/arch/hexagon/include/asm/elf.h
@@ -217,7 +217,8 @@ do {					\
 #define ELF_PLATFORM  (NULL)
 
 #ifdef __KERNEL__
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 #endif
 
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
diff --git a/arch/m32r/include/asm/elf.h b/arch/m32r/include/asm/elf.h
index b8da7d0..7089616 100644
--- a/arch/m32r/include/asm/elf.h
+++ b/arch/m32r/include/asm/elf.h
@@ -128,6 +128,7 @@ typedef elf_fpreg_t elf_fpregset_t;
    intent than poking at uname or /proc/cpuinfo.  */
 #define ELF_PLATFORM	(NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 
 #endif  /* _ASM_M32R__ELF_H */
diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h
index e9b7cda..f83c1d0 100644
--- a/arch/m68k/include/asm/elf.h
+++ b/arch/m68k/include/asm/elf.h
@@ -113,6 +113,7 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 
 #endif
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h
index 834849f..640ddd4 100644
--- a/arch/microblaze/include/asm/elf.h
+++ b/arch/microblaze/include/asm/elf.h
@@ -116,7 +116,8 @@ do {							\
 } while (0)
 
 #ifdef __KERNEL__
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
 #endif
 
 #endif /* __uClinux__ */
diff --git a/arch/mn10300/include/asm/elf.h b/arch/mn10300/include/asm/elf.h
index 8157c92..4ebd6b3 100644
--- a/arch/mn10300/include/asm/elf.h
+++ b/arch/mn10300/include/asm/elf.h
@@ -151,7 +151,8 @@ do {						\
 #define ELF_PLATFORM  (NULL)
 
 #ifdef __KERNEL__
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 #endif
 
 #endif /* _ASM_ELF_H */
diff --git a/arch/openrisc/include/asm/elf.h b/arch/openrisc/include/asm/elf.h
index a8fe2c5..225a7ff 100644
--- a/arch/openrisc/include/asm/elf.h
+++ b/arch/openrisc/include/asm/elf.h
@@ -110,7 +110,8 @@ extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt);
 
 #define ELF_PLATFORM	(NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 
 #endif /* __KERNEL__ */
 #endif
diff --git a/arch/score/include/asm/elf.h b/arch/score/include/asm/elf.h
index f478ce9..5d566c7 100644
--- a/arch/score/include/asm/elf.h
+++ b/arch/score/include/asm/elf.h
@@ -54,7 +54,7 @@ typedef elf_fpreg_t	elf_fpregset_t;
 
 #define SET_PERSONALITY(ex)					\
 do {								\
-	set_personality(PER_LINUX);				\
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
 } while (0)
 
 struct task_struct;
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index f38112b..37924af 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -183,7 +183,8 @@ do {									\
 } while (0)
 #endif
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
 
 #ifdef CONFIG_VSYSCALL
 /* vDSO has arch_setup_additional_pages */
diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
index 2d4d755..ac74a2c 100644
--- a/arch/sparc/include/asm/elf_32.h
+++ b/arch/sparc/include/asm/elf_32.h
@@ -128,6 +128,7 @@ typedef struct {
 
 #define ELF_PLATFORM	(NULL)
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
 
 #endif /* !(__ASMSPARC_ELF_H) */
diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h
index 6e65ead..5293312 100644
--- a/arch/xtensa/include/asm/elf.h
+++ b/arch/xtensa/include/asm/elf.h
@@ -189,7 +189,8 @@ typedef struct {
 #endif
 } elf_xtregs_t;
 
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) \
+	set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
 
 struct task_struct;
 
-- 
Jiri Kosina
SUSE Labs

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

* Re: [PATCH] [RFC] cross-arch: don't corrupt personality flags upon exec()
  2012-08-03 10:01 [PATCH] [RFC] cross-arch: don't corrupt personality flags upon exec() Jiri Kosina
@ 2012-08-13 13:19 ` Jiri Kosina
  2012-08-15 22:45   ` Andrew Morton
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Kosina @ 2012-08-13 13:19 UTC (permalink / raw)
  To: Haavard Skinnemoen, Hans-Christian Egtvedt, Mike Frysinger,
	Mark Salter, Mikael Starvik, Jesper Nilsson, David Howells,
	Yoshinori Sato, Richard Kuo, Hirokazu Takata, Geert Uytterhoeven,
	Michal Simek, Koichi Yasutake, Jonas Bonn, Chen Liqin, Lennox Wu,
	Paul Mundt, David S. Miller, Chris Zankel
  Cc: Andrew Morton, linux-kernel

On Fri, 3 Aug 2012, Jiri Kosina wrote:

> Historically, the top three bytes of personality have been used for things 
> such as ADDR_NO_RANDOMIZE, which made sense only for specific 
> architectures.
> 
> We now, however, have a flag there that is general no matter the 
> architecture (UNAME26); generally we have to be careful to preserve the 
> personality flags across exec().
> 
> This patch tries to fix all architectures that forcefully overwrite
> personality flags during exec() (ppc32 and s390 have been fixed recently 
> by commits f9783ec86 and 59e4c3a2f in a similar way already).
> 
> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
> ---
> 
> Untested, as I don't own the hardware.

Ping, Acks, Nacks, anyone?

Andrew, if noone has any objections, I guess this should perhaps go 
through -mm.

Thanks.

> 
>  arch/avr32/include/asm/elf.h      |    3 ++-
>  arch/blackfin/include/asm/elf.h   |    3 ++-
>  arch/c6x/include/asm/elf.h        |    3 ++-
>  arch/cris/include/asm/elf.h       |    3 ++-
>  arch/frv/include/asm/elf.h        |    3 ++-
>  arch/h8300/include/asm/elf.h      |    3 ++-
>  arch/hexagon/include/asm/elf.h    |    3 ++-
>  arch/m32r/include/asm/elf.h       |    3 ++-
>  arch/m68k/include/asm/elf.h       |    3 ++-
>  arch/microblaze/include/asm/elf.h |    3 ++-
>  arch/mn10300/include/asm/elf.h    |    3 ++-
>  arch/openrisc/include/asm/elf.h   |    3 ++-
>  arch/score/include/asm/elf.h      |    2 +-
>  arch/sh/include/asm/elf.h         |    3 ++-
>  arch/sparc/include/asm/elf_32.h   |    3 ++-
>  arch/xtensa/include/asm/elf.h     |    3 ++-
>  16 files changed, 31 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h
> index 3b3159b..e2c3287 100644
> --- a/arch/avr32/include/asm/elf.h
> +++ b/arch/avr32/include/asm/elf.h
> @@ -102,6 +102,7 @@ typedef struct user_fpu_struct elf_fpregset_t;
>  
>  #define ELF_PLATFORM  (NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
>  
>  #endif /* __ASM_AVR32_ELF_H */
> diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
> index e6c6812..14bc98f 100644
> --- a/arch/blackfin/include/asm/elf.h
> +++ b/arch/blackfin/include/asm/elf.h
> @@ -132,6 +132,7 @@ do {											\
>  
>  #define ELF_PLATFORM  (NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  
>  #endif
> diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h
> index f4552db..32b9971 100644
> --- a/arch/c6x/include/asm/elf.h
> +++ b/arch/c6x/include/asm/elf.h
> @@ -77,7 +77,8 @@ do {								\
>  
>  #define ELF_PLATFORM  (NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  
>  /* C6X specific section types */
>  #define SHT_C6000_UNWIND	0x70000001
> diff --git a/arch/cris/include/asm/elf.h b/arch/cris/include/asm/elf.h
> index 8a3d8e2..8182f2d 100644
> --- a/arch/cris/include/asm/elf.h
> +++ b/arch/cris/include/asm/elf.h
> @@ -86,6 +86,7 @@ typedef unsigned long elf_fpregset_t;
>  
>  #define ELF_PLATFORM  (NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  
>  #endif
> diff --git a/arch/frv/include/asm/elf.h b/arch/frv/include/asm/elf.h
> index c381980..9ccbc80 100644
> --- a/arch/frv/include/asm/elf.h
> +++ b/arch/frv/include/asm/elf.h
> @@ -137,6 +137,7 @@ do {											\
>  
>  #define ELF_PLATFORM  (NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  
>  #endif
> diff --git a/arch/h8300/include/asm/elf.h b/arch/h8300/include/asm/elf.h
> index c24fa25..41193c3 100644
> --- a/arch/h8300/include/asm/elf.h
> +++ b/arch/h8300/include/asm/elf.h
> @@ -54,7 +54,8 @@ typedef unsigned long elf_fpregset_t;
>  
>  #define ELF_PLATFORM  (NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  
>  #define R_H8_NONE       0
>  #define R_H8_DIR32      1
> diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h
> index 37976a0..82b4996 100644
> --- a/arch/hexagon/include/asm/elf.h
> +++ b/arch/hexagon/include/asm/elf.h
> @@ -217,7 +217,8 @@ do {					\
>  #define ELF_PLATFORM  (NULL)
>  
>  #ifdef __KERNEL__
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  #endif
>  
>  #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
> diff --git a/arch/m32r/include/asm/elf.h b/arch/m32r/include/asm/elf.h
> index b8da7d0..7089616 100644
> --- a/arch/m32r/include/asm/elf.h
> +++ b/arch/m32r/include/asm/elf.h
> @@ -128,6 +128,7 @@ typedef elf_fpreg_t elf_fpregset_t;
>     intent than poking at uname or /proc/cpuinfo.  */
>  #define ELF_PLATFORM	(NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  
>  #endif  /* _ASM_M32R__ELF_H */
> diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h
> index e9b7cda..f83c1d0 100644
> --- a/arch/m68k/include/asm/elf.h
> +++ b/arch/m68k/include/asm/elf.h
> @@ -113,6 +113,7 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
>  
>  #define ELF_PLATFORM  (NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  
>  #endif
> diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h
> index 834849f..640ddd4 100644
> --- a/arch/microblaze/include/asm/elf.h
> +++ b/arch/microblaze/include/asm/elf.h
> @@ -116,7 +116,8 @@ do {							\
>  } while (0)
>  
>  #ifdef __KERNEL__
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
>  #endif
>  
>  #endif /* __uClinux__ */
> diff --git a/arch/mn10300/include/asm/elf.h b/arch/mn10300/include/asm/elf.h
> index 8157c92..4ebd6b3 100644
> --- a/arch/mn10300/include/asm/elf.h
> +++ b/arch/mn10300/include/asm/elf.h
> @@ -151,7 +151,8 @@ do {						\
>  #define ELF_PLATFORM  (NULL)
>  
>  #ifdef __KERNEL__
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  #endif
>  
>  #endif /* _ASM_ELF_H */
> diff --git a/arch/openrisc/include/asm/elf.h b/arch/openrisc/include/asm/elf.h
> index a8fe2c5..225a7ff 100644
> --- a/arch/openrisc/include/asm/elf.h
> +++ b/arch/openrisc/include/asm/elf.h
> @@ -110,7 +110,8 @@ extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt);
>  
>  #define ELF_PLATFORM	(NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  
>  #endif /* __KERNEL__ */
>  #endif
> diff --git a/arch/score/include/asm/elf.h b/arch/score/include/asm/elf.h
> index f478ce9..5d566c7 100644
> --- a/arch/score/include/asm/elf.h
> +++ b/arch/score/include/asm/elf.h
> @@ -54,7 +54,7 @@ typedef elf_fpreg_t	elf_fpregset_t;
>  
>  #define SET_PERSONALITY(ex)					\
>  do {								\
> -	set_personality(PER_LINUX);				\
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
>  } while (0)
>  
>  struct task_struct;
> diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
> index f38112b..37924af 100644
> --- a/arch/sh/include/asm/elf.h
> +++ b/arch/sh/include/asm/elf.h
> @@ -183,7 +183,8 @@ do {									\
>  } while (0)
>  #endif
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
>  
>  #ifdef CONFIG_VSYSCALL
>  /* vDSO has arch_setup_additional_pages */
> diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
> index 2d4d755..ac74a2c 100644
> --- a/arch/sparc/include/asm/elf_32.h
> +++ b/arch/sparc/include/asm/elf_32.h
> @@ -128,6 +128,7 @@ typedef struct {
>  
>  #define ELF_PLATFORM	(NULL)
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>  
>  #endif /* !(__ASMSPARC_ELF_H) */
> diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h
> index 6e65ead..5293312 100644
> --- a/arch/xtensa/include/asm/elf.h
> +++ b/arch/xtensa/include/asm/elf.h
> @@ -189,7 +189,8 @@ typedef struct {
>  #endif
>  } elf_xtregs_t;
>  
> -#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
> +#define SET_PERSONALITY(ex) \
> +	set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK)))
>  
>  struct task_struct;

-- 
Jiri Kosina
SUSE Labs

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

* Re: [PATCH] [RFC] cross-arch: don't corrupt personality flags upon exec()
  2012-08-13 13:19 ` Jiri Kosina
@ 2012-08-15 22:45   ` Andrew Morton
  2012-08-22 19:27     ` Arnd Bergmann
  0 siblings, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2012-08-15 22:45 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Haavard Skinnemoen, Hans-Christian Egtvedt, Mike Frysinger,
	Mark Salter, Mikael Starvik, Jesper Nilsson, David Howells,
	Yoshinori Sato, Richard Kuo, Hirokazu Takata, Geert Uytterhoeven,
	Michal Simek, Koichi Yasutake, Jonas Bonn, Chen Liqin, Lennox Wu,
	Paul Mundt, David S. Miller, Chris Zankel, linux-kernel

On Mon, 13 Aug 2012 15:19:40 +0200 (CEST)
Jiri Kosina <jkosina@suse.cz> wrote:

> On Fri, 3 Aug 2012, Jiri Kosina wrote:
> 
> > Historically, the top three bytes of personality have been used for things 
> > such as ADDR_NO_RANDOMIZE, which made sense only for specific 
> > architectures.
> > 
> > We now, however, have a flag there that is general no matter the 
> > architecture (UNAME26); generally we have to be careful to preserve the 
> > personality flags across exec().
> > 
> > This patch tries to fix all architectures that forcefully overwrite
> > personality flags during exec() (ppc32 and s390 have been fixed recently 
> > by commits f9783ec86 and 59e4c3a2f in a similar way already).
> > 
> > Signed-off-by: Jiri Kosina <jkosina@suse.cz>
> > ---
> > 
> > Untested, as I don't own the hardware.
> 
> Ping, Acks, Nacks, anyone?

Silence means "I'll fix it if you broke it" ;)

> Andrew, if noone has any objections, I guess this should perhaps go 
> through -mm.

Sure.  But..


> > --- a/arch/blackfin/include/asm/elf.h
> > +++ b/arch/blackfin/include/asm/elf.h
> > @@ -132,6 +132,7 @@ do {											\
> >  
> >  #define ELF_PLATFORM  (NULL)
> >  
> > -#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
> > +#define SET_PERSONALITY(ex) \
> > +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))

This is repeated soooo many times.  Could we not just delete it and, in
include/linux/elf.h, do:

#ifndef SET_PERSONALITY
<that stuff>
#endif

?

If any SET_PERSONALITY-using code is including asm/elf.h directly then
it will reliably break and will get fixed.

Extra marks will be awarded if you can work out whether to use
PER_LINUX_32BIT ;)


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

* Re: [PATCH] [RFC] cross-arch: don't corrupt personality flags upon exec()
  2012-08-15 22:45   ` Andrew Morton
@ 2012-08-22 19:27     ` Arnd Bergmann
  2012-08-28 16:53       ` Chris Metcalf
  0 siblings, 1 reply; 7+ messages in thread
From: Arnd Bergmann @ 2012-08-22 19:27 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Jiri Kosina, Haavard Skinnemoen, Hans-Christian Egtvedt,
	Mike Frysinger, Mark Salter, Mikael Starvik, Jesper Nilsson,
	David Howells, Yoshinori Sato, Richard Kuo, Hirokazu Takata,
	Geert Uytterhoeven, Michal Simek, Koichi Yasutake, Jonas Bonn,
	Chen Liqin, Lennox Wu, Paul Mundt, David S. Miller, Chris Zankel,
	linux-kernel, Chris Metcalf

On Wednesday 15 August 2012, Andrew Morton wrote:
> Extra marks will be awarded if you can work out whether to use
> PER_LINUX_32BIT ;)

I'll try this:

PER_LINUX_32BIT is defined as (PER_LINUX | ADDR_LIMIT_32BIT).

The ADDR_LIMIT_32BIT flag is used in exactly two places in the kernel:

1. On alpha, it limits the available address space to 32 bits, in order to
  run certain legacy applications (Netscape) that are not 64 bit safe and were
  compiled with an interesting 32 bit user space mode with 64 bit syscalls.

2. on ARM, it is used to /not/ limit the user address space to 26 bits.
   For all practical purposes, one must set the ADDR_LIMIT_32BIT flag to
   run modern applications now.

The avr32, microblaze architectures always set PER_LINUX_32BIT because they
copied from ARM, but the flag has no effect there.

On tile, the PER_LINUX_32BIT is always set for 32 bit compat tasks in a 64 bit
kernel, which is harmless but wrong anyway. Also this, tile never calls
set_personality, which is also harmless because it just means that exec_domain
switching on tile is broken, but the only non-bogus exec_domain besides the
default one is an experimental support for Acorn RISC OS binaries that was
last updated in 2002 for for linux-2.5.49.

	Arnd

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

* Re: [PATCH] [RFC] cross-arch: don't corrupt personality flags upon exec()
  2012-08-22 19:27     ` Arnd Bergmann
@ 2012-08-28 16:53       ` Chris Metcalf
  2012-08-28 18:49         ` Jiri Kosina
  0 siblings, 1 reply; 7+ messages in thread
From: Chris Metcalf @ 2012-08-28 16:53 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Andrew Morton, Jiri Kosina, Haavard Skinnemoen,
	Hans-Christian Egtvedt, Mike Frysinger, Mark Salter,
	Mikael Starvik, Jesper Nilsson, David Howells, Yoshinori Sato,
	Richard Kuo, Hirokazu Takata, Geert Uytterhoeven, Michal Simek,
	Koichi Yasutake, Jonas Bonn, Chen Liqin, Lennox Wu, Paul Mundt,
	David S. Miller, Chris Zankel, linux-kernel

On 8/22/2012 3:27 PM, Arnd Bergmann wrote:
> On tile, the PER_LINUX_32BIT is always set for 32 bit compat tasks in a
> 64 bit kernel, which is harmless but wrong anyway. Also this, tile never
> calls set_personality, which is also harmless because it just means that
> exec_domain switching on tile is broken, but the only non-bogus
> exec_domain besides the default one is an experimental support for Acorn
> RISC OS binaries that was last updated in 2002 for for linux-2.5.49.

Arnd, thanks for the drive-by code review.  Is this change the correct fix
for your observation?

diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
index d16d006..fd31920 100644
--- a/arch/tile/include/asm/elf.h
+++ b/arch/tile/include/asm/elf.h
@@ -156,12 +156,12 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 #undef SET_PERSONALITY
 #define SET_PERSONALITY(ex) \
 do { \
-       current->personality = PER_LINUX; \
+       set_personality(PER_LINUX);                  \
        current_thread_info()->status &= ~TS_COMPAT; \
 } while (0)
 #define COMPAT_SET_PERSONALITY(ex) \
 do { \
-       current->personality = PER_LINUX_32BIT; \
+       set_personality(PER_LINUX);                 \
        current_thread_info()->status |= TS_COMPAT; \
 } while (0)

-- 
Chris Metcalf, Tilera Corp.
http://www.tilera.com


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

* Re: [PATCH] [RFC] cross-arch: don't corrupt personality flags upon exec()
  2012-08-28 16:53       ` Chris Metcalf
@ 2012-08-28 18:49         ` Jiri Kosina
  2012-08-28 19:04           ` Chris Metcalf
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Kosina @ 2012-08-28 18:49 UTC (permalink / raw)
  To: Chris Metcalf
  Cc: Arnd Bergmann, Andrew Morton, Haavard Skinnemoen,
	Hans-Christian Egtvedt, Mike Frysinger, Mark Salter,
	Mikael Starvik, Jesper Nilsson, David Howells, Yoshinori Sato,
	Richard Kuo, Hirokazu Takata, Geert Uytterhoeven, Michal Simek,
	Koichi Yasutake, Jonas Bonn, Chen Liqin, Lennox Wu, Paul Mundt,
	David S. Miller, Chris Zankel, linux-kernel

On Tue, 28 Aug 2012, Chris Metcalf wrote:

> > On tile, the PER_LINUX_32BIT is always set for 32 bit compat tasks in a
> > 64 bit kernel, which is harmless but wrong anyway. Also this, tile never
> > calls set_personality, which is also harmless because it just means that
> > exec_domain switching on tile is broken, but the only non-bogus
> > exec_domain besides the default one is an experimental support for Acorn
> > RISC OS binaries that was last updated in 2002 for for linux-2.5.49.
> 
> Arnd, thanks for the drive-by code review.  Is this change the correct fix
> for your observation?
> 
> diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
> index d16d006..fd31920 100644
> --- a/arch/tile/include/asm/elf.h
> +++ b/arch/tile/include/asm/elf.h
> @@ -156,12 +156,12 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
>  #undef SET_PERSONALITY
>  #define SET_PERSONALITY(ex) \
>  do { \
> -       current->personality = PER_LINUX; \
> +       set_personality(PER_LINUX);                  \
>         current_thread_info()->status &= ~TS_COMPAT; \
>  } while (0)
>  #define COMPAT_SET_PERSONALITY(ex) \
>  do { \
> -       current->personality = PER_LINUX_32BIT; \
> +       set_personality(PER_LINUX);                 \
>         current_thread_info()->status |= TS_COMPAT; \
>  } while (0)

Actually this is also wrong. You should be rather doing

	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))

otherwise you clobber the upper personality bits upon exec().

Something like the patch below. Either you can take it for tile, or I can 
ask Andrew to fold it into my tree-wide fix currently waiting in -mm. Just 
let me know.


From: Jiri Kosina <jkosina@suse.cz>
Subject: [PATCH] tile: Don't corrupt personality flags upon exec()

Historically, the top three bytes of personality have been used for things
such as ADDR_NO_RANDOMIZE, which made sense only for specific
architectures.

We now however have a flag there that is general no matter the
architecture (UNAME26); generally we have to be careful to preserve the
personality flags across exec().

This patch fixes tile architecture not to forcefully overwrite
personality flags during exec().

Plus it fixes exec_domain switching -- set_personality() should always be 
used instead of directly assigning to current->personality.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
---
 arch/tile/include/asm/elf.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
index d16d006..cf7f3bd 100644
--- a/arch/tile/include/asm/elf.h
+++ b/arch/tile/include/asm/elf.h
@@ -156,12 +156,12 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 #undef SET_PERSONALITY
 #define SET_PERSONALITY(ex) \
 do { \
-	current->personality = PER_LINUX; \
+	set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
 	current_thread_info()->status &= ~TS_COMPAT; \
 } while (0)
 #define COMPAT_SET_PERSONALITY(ex) \
 do { \
-	current->personality = PER_LINUX_32BIT; \
+	set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK))); \
 	current_thread_info()->status |= TS_COMPAT; \
 } while (0)
 

-- 
Jiri Kosina
SUSE Labs

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

* Re: [PATCH] [RFC] cross-arch: don't corrupt personality flags upon exec()
  2012-08-28 18:49         ` Jiri Kosina
@ 2012-08-28 19:04           ` Chris Metcalf
  0 siblings, 0 replies; 7+ messages in thread
From: Chris Metcalf @ 2012-08-28 19:04 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Arnd Bergmann, Andrew Morton, Haavard Skinnemoen,
	Hans-Christian Egtvedt, Mike Frysinger, Mark Salter,
	Mikael Starvik, Jesper Nilsson, David Howells, Yoshinori Sato,
	Richard Kuo, Hirokazu Takata, Geert Uytterhoeven, Michal Simek,
	Koichi Yasutake, Jonas Bonn, Chen Liqin, Lennox Wu, Paul Mundt,
	David S. Miller, Chris Zankel, linux-kernel

On 8/28/2012 2:49 PM, Jiri Kosina wrote:
> On Tue, 28 Aug 2012, Chris Metcalf wrote:
>>> On tile, the PER_LINUX_32BIT is always set for 32 bit compat tasks in a
>>> 64 bit kernel, which is harmless but wrong anyway. Also this, tile never
>>> calls set_personality, which is also harmless because it just means that
>>> exec_domain switching on tile is broken, but the only non-bogus
>>> exec_domain besides the default one is an experimental support for Acorn
>>> RISC OS binaries that was last updated in 2002 for for linux-2.5.49.
>> Arnd, thanks for the drive-by code review.  Is this change the correct fix
>> for your observation?
>>
>> diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
>> index d16d006..fd31920 100644
>> --- a/arch/tile/include/asm/elf.h
>> +++ b/arch/tile/include/asm/elf.h
>> @@ -156,12 +156,12 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
>>  #undef SET_PERSONALITY
>>  #define SET_PERSONALITY(ex) \
>>  do { \
>> -       current->personality = PER_LINUX; \
>> +       set_personality(PER_LINUX);                  \
>>         current_thread_info()->status &= ~TS_COMPAT; \
>>  } while (0)
>>  #define COMPAT_SET_PERSONALITY(ex) \
>>  do { \
>> -       current->personality = PER_LINUX_32BIT; \
>> +       set_personality(PER_LINUX);                 \
>>         current_thread_info()->status |= TS_COMPAT; \
>>  } while (0)
> Actually this is also wrong. You should be rather doing
>
> 	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
>
> otherwise you clobber the upper personality bits upon exec().
>
> Something like the patch below. Either you can take it for tile, or I can 
> ask Andrew to fold it into my tree-wide fix currently waiting in -mm. Just 
> let me know.

It looks fine for tile, except that your change still uses PER_LINUX_32BIT,
which Arnd points out is wrong; my proposed patch changed it to just
PER_LINUX, though I'm not completely clear as to whether this is correct. 
The tilegx compat mode is an ILP32 mode where the compiler emits 32-bit Elf
binaries and the compat layer is used to translate to and from 32-bit
pointer and long, but nothing else.  It sounds like PER_LINUX applies
better than PER_LINUX_32BIT based on the fact that the extra 32-bit flag
isn't actually used in any architecture-independent code (nor in tile code,
which just checks whether something is a compat task per se, rather than
looking at the personality bits).

Since you have a treewide fix going anyway, I'm happy for you to push this
to Andrew.  If it's OK with the one suggested change, you can add my

Acked-by: Chris Metcalf <cmetcalf@tilera.com>

-- 
Chris Metcalf, Tilera Corp.
http://www.tilera.com


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

end of thread, other threads:[~2012-08-28 19:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-03 10:01 [PATCH] [RFC] cross-arch: don't corrupt personality flags upon exec() Jiri Kosina
2012-08-13 13:19 ` Jiri Kosina
2012-08-15 22:45   ` Andrew Morton
2012-08-22 19:27     ` Arnd Bergmann
2012-08-28 16:53       ` Chris Metcalf
2012-08-28 18:49         ` Jiri Kosina
2012-08-28 19:04           ` Chris Metcalf

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