Skip to content

Commit 9f0b480

Browse files
jmberg-intelrichardweinberger
authored andcommitted
um: rework userspace stubs to not hard-code stub location
The userspace stacks mostly have a stack (and in the case of the syscall stub we can just set their stack pointer) that points to the location of the stub data page already. Rework the stubs to use the stack pointer to derive the start of the data page, rather than requiring it to be hard-coded. In the clone stub, also integrate the int3 into the stack remap, since we really must not use the stack while we remap it. This prepares for putting the stub at a variable location that's not part of the normal address space of the userspace processes running inside the UML machine. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Richard Weinberger <richard@nod.at>
1 parent 84b2789 commit 9f0b480

File tree

9 files changed

+75
-48
lines changed

9 files changed

+75
-48
lines changed

arch/um/include/shared/as-layout.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,10 @@
2020
* 'UL' and other type specifiers unilaterally. We
2121
* use the following macros to deal with this.
2222
*/
23-
24-
#ifdef __ASSEMBLY__
25-
#define _UML_AC(X, Y) (Y)
26-
#else
27-
#define __UML_AC(X, Y) (X(Y))
28-
#define _UML_AC(X, Y) __UML_AC(X, Y)
29-
#endif
30-
31-
#define STUB_START _UML_AC(, 0x100000)
32-
#define STUB_CODE _UML_AC((unsigned long), STUB_START)
33-
#define STUB_DATA _UML_AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
34-
#define STUB_END _UML_AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
23+
#define STUB_START 0x100000UL
24+
#define STUB_CODE STUB_START
25+
#define STUB_DATA (STUB_CODE + UM_KERN_PAGE_SIZE)
26+
#define STUB_END (STUB_DATA + UM_KERN_PAGE_SIZE)
3527

3628
#ifndef __ASSEMBLY__
3729

arch/um/include/shared/common-offsets.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
/* for use by sys-$SUBARCH/kernel-offsets.c */
3+
#include <stub-data.h>
34

45
DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
56

@@ -43,3 +44,8 @@ DEFINE(UML_CONFIG_64BIT, CONFIG_64BIT);
4344
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
4445
DEFINE(UML_CONFIG_UML_TIME_TRAVEL_SUPPORT, CONFIG_UML_TIME_TRAVEL_SUPPORT);
4546
#endif
47+
48+
/* for stub */
49+
DEFINE(UML_STUB_FIELD_OFFSET, offsetof(struct stub_data, offset));
50+
DEFINE(UML_STUB_FIELD_CHILD_ERR, offsetof(struct stub_data, child_err));
51+
DEFINE(UML_STUB_FIELD_FD, offsetof(struct stub_data, fd));

arch/um/kernel/skas/clone.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ stub_clone_handler(void)
4141
goto done;
4242
}
4343

44-
remap_stack(data->fd, data->offset);
45-
goto done;
44+
remap_stack_and_trap();
4645

4746
done:
4847
trap_myself();

arch/um/os-Linux/skas/mem.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ static int __init init_syscall_regs(void)
4040
syscall_regs[REGS_IP_INDEX] = STUB_CODE +
4141
((unsigned long) batch_syscall_stub -
4242
(unsigned long) __syscall_stub_start);
43+
syscall_regs[REGS_SP_INDEX] = STUB_DATA;
44+
4345
return 0;
4446
}
4547

arch/x86/um/shared/sysdep/stub_32.h

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#define __SYSDEP_STUB_H
88

99
#include <asm/ptrace.h>
10+
#include <generated/asm-offsets.h>
1011

11-
#define STUB_SYSCALL_RET EAX
1212
#define STUB_MMAP_NR __NR_mmap2
1313
#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT)
1414

@@ -77,17 +77,28 @@ static inline void trap_myself(void)
7777
__asm("int3");
7878
}
7979

80-
static inline void remap_stack(int fd, unsigned long offset)
80+
static void inline remap_stack_and_trap(void)
8181
{
82-
__asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;"
83-
"movl %7, %%ebx ; movl %%eax, (%%ebx)"
84-
: : "g" (STUB_MMAP_NR), "b" (STUB_DATA),
85-
"c" (UM_KERN_PAGE_SIZE),
86-
"d" (PROT_READ | PROT_WRITE),
87-
"S" (MAP_FIXED | MAP_SHARED), "D" (fd),
88-
"a" (offset),
89-
"i" (&((struct stub_data *) STUB_DATA)->child_err)
90-
: "memory");
82+
__asm__ volatile (
83+
"movl %%esp,%%ebx ;"
84+
"andl %0,%%ebx ;"
85+
"movl %1,%%eax ;"
86+
"movl %%ebx,%%edi ; addl %2,%%edi ; movl (%%edi),%%edi ;"
87+
"movl %%ebx,%%ebp ; addl %3,%%ebp ; movl (%%ebp),%%ebp ;"
88+
"int $0x80 ;"
89+
"addl %4,%%ebx ; movl %%eax, (%%ebx) ;"
90+
"int $3"
91+
: :
92+
"g" (~(UM_KERN_PAGE_SIZE - 1)),
93+
"g" (STUB_MMAP_NR),
94+
"g" (UML_STUB_FIELD_FD),
95+
"g" (UML_STUB_FIELD_OFFSET),
96+
"g" (UML_STUB_FIELD_CHILD_ERR),
97+
"c" (UM_KERN_PAGE_SIZE),
98+
"d" (PROT_READ | PROT_WRITE),
99+
"S" (MAP_FIXED | MAP_SHARED)
100+
:
101+
"memory");
91102
}
92103

93104
#endif

arch/x86/um/shared/sysdep/stub_64.h

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#define __SYSDEP_STUB_H
88

99
#include <sysdep/ptrace_user.h>
10+
#include <generated/asm-offsets.h>
1011

11-
#define STUB_SYSCALL_RET PT_INDEX(RAX)
1212
#define STUB_MMAP_NR __NR_mmap
1313
#define MMAP_OFFSET(o) (o)
1414

@@ -82,18 +82,30 @@ static inline void trap_myself(void)
8282
__asm("int3");
8383
}
8484

85-
static inline void remap_stack(long fd, unsigned long offset)
85+
static inline void remap_stack_and_trap(void)
8686
{
87-
__asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; "
88-
"movq %6, %%r9; " __syscall "; movq %7, %%rbx ; "
89-
"movq %%rax, (%%rbx)":
90-
: "a" (STUB_MMAP_NR), "D" (STUB_DATA),
91-
"S" (UM_KERN_PAGE_SIZE),
92-
"d" (PROT_READ | PROT_WRITE),
93-
"g" (MAP_FIXED | MAP_SHARED), "g" (fd),
94-
"g" (offset),
95-
"i" (&((struct stub_data *) STUB_DATA)->child_err)
96-
: __syscall_clobber, "r10", "r8", "r9" );
87+
__asm__ volatile (
88+
"movq %0,%%rax ;"
89+
"movq %%rsp,%%rdi ;"
90+
"andq %1,%%rdi ;"
91+
"movq %2,%%r10 ;"
92+
"movq %%rdi,%%r8 ; addq %3,%%r8 ; movq (%%r8),%%r8 ;"
93+
"movq %%rdi,%%r9 ; addq %4,%%r9 ; movq (%%r9),%%r9 ;"
94+
__syscall ";"
95+
"movq %%rsp,%%rdi ; andq %1,%%rdi ;"
96+
"addq %5,%%rdi ; movq %%rax, (%%rdi) ;"
97+
"int3"
98+
: :
99+
"g" (STUB_MMAP_NR),
100+
"g" (~(UM_KERN_PAGE_SIZE - 1)),
101+
"g" (MAP_FIXED | MAP_SHARED),
102+
"g" (UML_STUB_FIELD_FD),
103+
"g" (UML_STUB_FIELD_OFFSET),
104+
"g" (UML_STUB_FIELD_CHILD_ERR),
105+
"S" (UM_KERN_PAGE_SIZE),
106+
"d" (PROT_READ | PROT_WRITE)
107+
:
108+
__syscall_clobber, "r10", "r8", "r9");
97109
}
98110

99111
#endif

arch/x86/um/stub_32.S

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,22 @@
55

66
.globl batch_syscall_stub
77
batch_syscall_stub:
8-
/* load pointer to first operation */
9-
mov $(STUB_DATA+8), %esp
10-
8+
/* %esp comes in as "top of page" */
9+
mov %esp, %ecx
10+
/* %esp has pointer to first operation */
11+
add $8, %esp
1112
again:
1213
/* load length of additional data */
1314
mov 0x0(%esp), %eax
1415

1516
/* if(length == 0) : end of list */
1617
/* write possible 0 to header */
17-
mov %eax, STUB_DATA+4
18+
mov %eax, 0x4(%ecx)
1819
cmpl $0, %eax
1920
jz done
2021

2122
/* save current pointer */
22-
mov %esp, STUB_DATA+4
23+
mov %esp, 0x4(%ecx)
2324

2425
/* skip additional data */
2526
add %eax, %esp
@@ -38,14 +39,18 @@ again:
3839
/* execute syscall */
3940
int $0x80
4041

42+
/* restore top of page pointer in %ecx */
43+
mov %esp, %ecx
44+
andl $(~UM_KERN_PAGE_SIZE) + 1, %ecx
45+
4146
/* check return value */
4247
pop %ebx
4348
cmp %ebx, %eax
4449
je again
4550

4651
done:
4752
/* save return value */
48-
mov %eax, STUB_DATA
53+
mov %eax, (%ecx)
4954

5055
/* stop */
5156
int3

arch/x86/um/stub_64.S

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
.section .__syscall_stub, "ax"
55
.globl batch_syscall_stub
66
batch_syscall_stub:
7-
mov $(STUB_DATA), %rbx
8-
/* load pointer to first operation */
9-
mov %rbx, %rsp
7+
/* %rsp has the pointer to first operation */
8+
mov %rsp, %rbx
109
add $0x10, %rsp
1110
again:
1211
/* load length of additional data */

arch/x86/um/stub_segv.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
void __attribute__ ((__section__ (".__syscall_stub")))
1212
stub_segv_handler(int sig, siginfo_t *info, void *p)
1313
{
14+
int stack;
1415
ucontext_t *uc = p;
16+
struct faultinfo *f = (void *)(((unsigned long)&stack) & ~(UM_KERN_PAGE_SIZE - 1));
1517

16-
GET_FAULTINFO_FROM_MC(*((struct faultinfo *) STUB_DATA),
17-
&uc->uc_mcontext);
18+
GET_FAULTINFO_FROM_MC(*f, &uc->uc_mcontext);
1819
trap_myself();
1920
}
2021

0 commit comments

Comments
 (0)