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