linux/arch
Dmitry Safonov ada26481df x86/mm: Make in_compat_syscall() work during exec
The x86 mmap() code selects the mmap base for an allocation depending on
the bitness of the syscall. For 64bit sycalls it select mm->mmap_base and
for 32bit mm->mmap_compat_base.

On execve the registers of the task invoking exec() are copied to the child
pt_regs. So child->pt_regs->orig_ax contains the execve syscall number of the
parent.

exec() calls mmap() which in turn uses in_compat_syscall() to check whether
the mapping is for a 32bit or a 64bit task. The decision is made on the
following criteria:

  ia32	  child->thread.status & TS_COMPAT
   x32	  child->pt_regs.orig_ax & __X32_SYSCALL_BIT
  ia64	  !ia32 && !x32 

child->thread.status is corretly set up in set_personality_*(), but the
syscall number in child->pt_regs.orig_ax is left unmodified.

Therefore the parent/child combinations work or fail in the following way:

Parent Child Child->thread_status  child->pt_regs.orig_ax  in_compat()  Works
ia64    ia64   TS_COMPAT == 0	   __X32_SYSCALL_BIT == 0     false       Y
ia64    ia32   TS_COMPAT == 1	   __X32_SYSCALL_BIT == 0     true        Y
ia64     x32   TS_COMPAT == 0	   __X32_SYSCALL_BIT == 0     false       N
ia32    ia64   TS_COMPAT == 0	   __X32_SYSCALL_BIT == 0     false       Y
ia32    ia32   TS_COMPAT == 1	   __X32_SYSCALL_BIT == 0     true        Y
ia32     x32   TS_COMPAT == 0	   __X32_SYSCALL_BIT == 0     false       N
 x32    ia64   TS_COMPAT == 0	   __X32_SYSCALL_BIT == 1     true        N
 x32    ia32   TS_COMPAT == 1	   __X32_SYSCALL_BIT == 1     true        Y
 x32     x32   TS_COMPAT == 0	   __X32_SYSCALL_BIT == 1     true        Y

Make set_personality_*() store the syscall number incl. __X32_SYSCALL_BIT
which corresponds to the newly started ELF executable in the childs
pt_regs, i.e. pretend that the exec was invoked from a task with the same
executable format.

So both thread.status and pt_regs.orig_ax correspond to the new ELF format
and in_compat_syscall() returns the correct result.

[ tglx: Rewrote changelog ]

Fixes: commit 1b028f784e ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()")
Reported-by: Adam Borowski <kilobyte@angband.pl>
Suggested-by: H. Peter Anvin <hpa@zytor.com>
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Cc: 0x7f454c46@gmail.com
Cc: linux-mm@kvack.org
Cc: Andrei Vagin <avagin@gmail.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Link: http://lkml.kernel.org/r/20170331111137.28170-1-dsafonov@virtuozzo.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2017-03-31 16:53:02 +02:00
..
alpha sched/headers: Move task->mm handling methods to <linux/sched/mm.h> 2017-03-03 01:43:28 +01:00
arc arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
arm x86/mm/gup: Switch GUP to the generic get_user_page_fast() implementation 2017-03-18 09:48:03 +01:00
arm64 x86/mm/gup: Switch GUP to the generic get_user_page_fast() implementation 2017-03-18 09:48:03 +01:00
avr32 arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
blackfin sched/headers: Move task->mm handling methods to <linux/sched/mm.h> 2017-03-03 01:43:28 +01:00
c6x sched/headers: Prepare for new header dependencies before moving code to <linux/sched/task_stack.h> 2017-03-02 08:42:36 +01:00
cris Merge branch 'prep-for-5level' 2017-03-10 08:59:07 -08:00
frv arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
h8300 arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
hexagon arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
ia64 arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
m32r sched/headers: Move task->mm handling methods to <linux/sched/mm.h> 2017-03-03 01:43:28 +01:00
m68k sched/headers: Prepare to remove the <linux/mm_types.h> dependency from <linux/sched.h> 2017-03-02 08:42:37 +01:00
metag arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
microblaze arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
mips arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
mn10300 arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
nios2 arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
openrisc arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
parisc Merge branch 'parisc-4.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux 2017-03-03 16:20:06 -08:00
powerpc x86/mm/gup: Switch GUP to the generic get_user_page_fast() implementation 2017-03-18 09:48:03 +01:00
s390 mm/gup: Drop the arch_pte_access_permitted() MMU callback 2017-03-18 09:48:01 +01:00
score Fixup for arch/score after extable.h introduction 2017-03-11 14:16:50 -08:00
sh Merge branch 'prep-for-5level' 2017-03-10 08:59:07 -08:00
sparc arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
tile arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
um Merge branch 'x86/process' into x86/mm, to create new base for further patches 2017-03-23 08:28:19 +01:00
unicore32 mm/gup: Drop the arch_pte_access_permitted() MMU callback 2017-03-18 09:48:01 +01:00
x86 x86/mm: Make in_compat_syscall() work during exec 2017-03-31 16:53:02 +02:00
xtensa arch, mm: convert all architectures to use 5level-fixup.h 2017-03-09 11:48:47 -08:00
.gitignore
Kconfig x86/mm: Introduce mmap_compat_base() for 32-bit mmap() 2017-03-13 14:59:22 +01:00