Skip to content

Commit a846446

Browse files
0x7f454c46KAGA-KOKO
authored andcommitted
x86/compat: Adjust in_compat_syscall() to generic code under !COMPAT
The result of in_compat_syscall() can be pictured as: x86 platform: --------------------------------------------------- | Arch\syscall | 64-bit | ia32 | x32 | |-------------------------------------------------| | x86_64 | false | true | true | |-------------------------------------------------| | i686 | | <true> | | --------------------------------------------------- Other platforms: ------------------------------------------- | Arch\syscall | 64-bit | compat | |-----------------------------------------| | 64-bit | false | true | |-----------------------------------------| | 32-bit(?) | | <false> | ------------------------------------------- As seen, the result of in_compat_syscall() on generic 32-bit platform differs from i686. There is no reason for in_compat_syscall() == true on native i686. It also easy to misread code if the result on native 32-bit platform differs between arches. Because of that non arch-specific code has many places with: if (IS_ENABLED(CONFIG_COMPAT) && in_compat_syscall()) in different variations. It looks-like the only non-x86 code which uses in_compat_syscall() not under CONFIG_COMPAT guard is in amd/amdkfd. But according to the commit a18069c ("amdkfd: Disable support for 32-bit user processes"), it actually should be disabled on native i686. Rename in_compat_syscall() to in_32bit_syscall() for x86-specific code and make in_compat_syscall() false under !CONFIG_COMPAT. A follow on patch will clean up generic users which were forced to check IS_ENABLED(CONFIG_COMPAT) with in_compat_syscall(). Signed-off-by: Dmitry Safonov <dima@arista.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Andy Lutomirski <luto@kernel.org> Cc: Dmitry Safonov <0x7f454c46@gmail.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: John Stultz <john.stultz@linaro.org> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Steffen Klassert <steffen.klassert@secunet.com> Cc: Stephen Boyd <sboyd@kernel.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: linux-efi@vger.kernel.org Cc: netdev@vger.kernel.org Link: https://lkml.kernel.org/r/20181012134253.23266-2-dima@arista.com
1 parent c6ee7a5 commit a846446

File tree

7 files changed

+22
-16
lines changed

7 files changed

+22
-16
lines changed

arch/x86/include/asm/compat.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,18 @@ static inline bool in_x32_syscall(void)
217217
return false;
218218
}
219219

220-
static inline bool in_compat_syscall(void)
220+
static inline bool in_32bit_syscall(void)
221221
{
222222
return in_ia32_syscall() || in_x32_syscall();
223223
}
224+
225+
#ifdef CONFIG_COMPAT
226+
static inline bool in_compat_syscall(void)
227+
{
228+
return in_32bit_syscall();
229+
}
224230
#define in_compat_syscall in_compat_syscall /* override the generic impl */
231+
#endif
225232

226233
struct compat_siginfo;
227234
int __copy_siginfo_to_user32(struct compat_siginfo __user *to,

arch/x86/include/asm/ftrace.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,7 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name
7676
#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS 1
7777
static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
7878
{
79-
if (in_compat_syscall())
80-
return true;
81-
return false;
79+
return in_32bit_syscall();
8280
}
8381
#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_IA32_EMULATION */
8482
#endif /* !COMPILE_OFFSETS */

arch/x86/kernel/process_64.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,10 +701,10 @@ static void __set_personality_x32(void)
701701
current->mm->context.ia32_compat = TIF_X32;
702702
current->personality &= ~READ_IMPLIES_EXEC;
703703
/*
704-
* in_compat_syscall() uses the presence of the x32 syscall bit
704+
* in_32bit_syscall() uses the presence of the x32 syscall bit
705705
* flag to determine compat status. The x86 mmap() code relies on
706706
* the syscall bitness so set x32 syscall bit right here to make
707-
* in_compat_syscall() work during exec().
707+
* in_32bit_syscall() work during exec().
708708
*
709709
* Pretend to come from a x32 execve.
710710
*/

arch/x86/kernel/sys_x86_64.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
105105
static void find_start_end(unsigned long addr, unsigned long flags,
106106
unsigned long *begin, unsigned long *end)
107107
{
108-
if (!in_compat_syscall() && (flags & MAP_32BIT)) {
108+
if (!in_32bit_syscall() && (flags & MAP_32BIT)) {
109109
/* This is usually used needed to map code in small
110110
model, so it needs to be in the first 31bit. Limit
111111
it to that. This means we need to move the
@@ -122,7 +122,7 @@ static void find_start_end(unsigned long addr, unsigned long flags,
122122
}
123123

124124
*begin = get_mmap_base(1);
125-
if (in_compat_syscall())
125+
if (in_32bit_syscall())
126126
*end = task_size_32bit();
127127
else
128128
*end = task_size_64bit(addr > DEFAULT_MAP_WINDOW);
@@ -193,7 +193,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
193193
return addr;
194194

195195
/* for MAP_32BIT mappings we force the legacy mmap base */
196-
if (!in_compat_syscall() && (flags & MAP_32BIT))
196+
if (!in_32bit_syscall() && (flags & MAP_32BIT))
197197
goto bottomup;
198198

199199
/* requesting a specific address */
@@ -217,9 +217,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
217217
* If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
218218
* in the full address space.
219219
*
220-
* !in_compat_syscall() check to avoid high addresses for x32.
220+
* !in_32bit_syscall() check to avoid high addresses for x32
221+
* (and make it no op on native i386).
221222
*/
222-
if (addr > DEFAULT_MAP_WINDOW && !in_compat_syscall())
223+
if (addr > DEFAULT_MAP_WINDOW && !in_32bit_syscall())
223224
info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW;
224225

225226
info.align_mask = 0;

arch/x86/mm/hugetlbpage.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
9292
* If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
9393
* in the full address space.
9494
*/
95-
info.high_limit = in_compat_syscall() ?
95+
info.high_limit = in_32bit_syscall() ?
9696
task_size_32bit() : task_size_64bit(addr > DEFAULT_MAP_WINDOW);
9797

9898
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
@@ -116,7 +116,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
116116
* If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
117117
* in the full address space.
118118
*/
119-
if (addr > DEFAULT_MAP_WINDOW && !in_compat_syscall())
119+
if (addr > DEFAULT_MAP_WINDOW && !in_32bit_syscall())
120120
info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW;
121121

122122
info.align_mask = PAGE_MASK & ~huge_page_mask(h);

arch/x86/mm/mmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ unsigned long get_mmap_base(int is_legacy)
166166
struct mm_struct *mm = current->mm;
167167

168168
#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
169-
if (in_compat_syscall()) {
169+
if (in_32bit_syscall()) {
170170
return is_legacy ? mm->mmap_compat_legacy_base
171171
: mm->mmap_compat_base;
172172
}

include/linux/compat.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,9 +1029,9 @@ int kcompat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
10291029
#else /* !CONFIG_COMPAT */
10301030

10311031
#define is_compat_task() (0)
1032-
#ifndef in_compat_syscall
1032+
/* Ensure no one redefines in_compat_syscall() under !CONFIG_COMPAT */
1033+
#define in_compat_syscall in_compat_syscall
10331034
static inline bool in_compat_syscall(void) { return false; }
1034-
#endif
10351035

10361036
#endif /* CONFIG_COMPAT */
10371037

0 commit comments

Comments
 (0)