Skip to content

Commit adf9ae0

Browse files
jmberg-intelrichardweinberger
authored andcommitted
um: fix stub location calculation
In commit 9f0b480 ("um: rework userspace stubs to not hard-code stub location") I changed stub_segv_handler() to do a calculation with a pointer to a stack variable to find the data page that we're using for the stack and the rest of the data. This same commit was meant to do it as well for stub_clone_handler(), but the change inadvertently went into commit 84b2789 ("um: separate child and parent errors in clone stub") instead. This was reported to not be compiled correctly by gcc 5, causing the code to crash here. I'm not sure why, perhaps it's UB because the var isn't initialized? In any case, this trick always seemed bad, so just create a new inline function that does the calculation in assembly. Reported-by: subashab@codeaurora.org Fixes: 9f0b480 ("um: rework userspace stubs to not hard-code stub location") Fixes: 84b2789 ("um: separate child and parent errors in clone stub") Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Richard Weinberger <richard@nod.at>
1 parent 6a241d2 commit adf9ae0

File tree

4 files changed

+26
-4
lines changed

4 files changed

+26
-4
lines changed

arch/um/kernel/skas/clone.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424
void __attribute__ ((__section__ (".__syscall_stub")))
2525
stub_clone_handler(void)
2626
{
27-
int stack;
28-
struct stub_data *data = (void *) ((unsigned long)&stack & ~(UM_KERN_PAGE_SIZE - 1));
27+
struct stub_data *data = get_stub_page();
2928
long err;
3029

3130
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,16 @@ static inline void remap_stack_and_trap(void)
101101
"memory");
102102
}
103103

104+
static __always_inline void *get_stub_page(void)
105+
{
106+
unsigned long ret;
107+
108+
asm volatile (
109+
"movl %%esp,%0 ;"
110+
"andl %1,%0"
111+
: "=a" (ret)
112+
: "g" (~(UM_KERN_PAGE_SIZE - 1)));
113+
114+
return (void *)ret;
115+
}
104116
#endif

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,16 @@ static inline void remap_stack_and_trap(void)
108108
__syscall_clobber, "r10", "r8", "r9");
109109
}
110110

111+
static __always_inline void *get_stub_page(void)
112+
{
113+
unsigned long ret;
114+
115+
asm volatile (
116+
"movq %%rsp,%0 ;"
117+
"andq %1,%0"
118+
: "=a" (ret)
119+
: "g" (~(UM_KERN_PAGE_SIZE - 1)));
120+
121+
return (void *)ret;
122+
}
111123
#endif

arch/x86/um/stub_segv.c

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

1817
GET_FAULTINFO_FROM_MC(*f, &uc->uc_mcontext);
1918
trap_myself();

0 commit comments

Comments
 (0)