Skip to content

Commit 84b2789

Browse files
jmberg-intelrichardweinberger
authored andcommitted
um: separate child and parent errors in clone stub
If the two are mixed up, then it looks as though the parent returned an error if the child failed (before) the mmap(), and then the resulting process never gets killed. Fix this by splitting the child and parent errors, reporting and using them appropriately. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Richard Weinberger <richard@nod.at>
1 parent a7d4888 commit 84b2789

File tree

5 files changed

+27
-27
lines changed

5 files changed

+27
-27
lines changed

arch/um/include/shared/skas/stub-data.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
struct stub_data {
1212
unsigned long offset;
1313
int fd;
14-
long err;
14+
long parent_err, child_err;
1515
};
1616

1717
#endif

arch/um/kernel/skas/clone.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,26 @@
2424
void __attribute__ ((__section__ (".__syscall_stub")))
2525
stub_clone_handler(void)
2626
{
27-
struct stub_data *data = (struct stub_data *) STUB_DATA;
27+
int stack;
28+
struct stub_data *data = (void *) ((unsigned long)&stack & ~(UM_KERN_PAGE_SIZE - 1));
2829
long err;
2930

3031
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
31-
STUB_DATA + UM_KERN_PAGE_SIZE / 2 - sizeof(void *));
32-
if (err != 0)
33-
goto out;
32+
(unsigned long)data + UM_KERN_PAGE_SIZE / 2 - sizeof(void *));
33+
if (err) {
34+
data->parent_err = err;
35+
goto done;
36+
}
3437

3538
err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
36-
if (err)
37-
goto out;
39+
if (err) {
40+
data->child_err = err;
41+
goto done;
42+
}
3843

3944
remap_stack(data->fd, data->offset);
4045
goto done;
4146

42-
out:
43-
/*
44-
* save current result.
45-
* Parent: pid;
46-
* child: retcode of mmap already saved and it jumps around this
47-
* assignment
48-
*/
49-
data->err = err;
5047
done:
5148
trap_myself();
5249
}

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

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -545,8 +545,14 @@ int copy_context_skas0(unsigned long new_stack, int pid)
545545
* and child's mmap2 calls
546546
*/
547547
*data = ((struct stub_data) {
548-
.offset = MMAP_OFFSET(new_offset),
549-
.fd = new_fd
548+
.offset = MMAP_OFFSET(new_offset),
549+
.fd = new_fd,
550+
.parent_err = -ESRCH,
551+
.child_err = 0,
552+
});
553+
554+
*child_data = ((struct stub_data) {
555+
.child_err = -ESRCH,
550556
});
551557

552558
err = ptrace_setregs(pid, thread_regs);
@@ -564,9 +570,6 @@ int copy_context_skas0(unsigned long new_stack, int pid)
564570
return err;
565571
}
566572

567-
/* set a well known return code for detection of child write failure */
568-
child_data->err = 12345678;
569-
570573
/*
571574
* Wait, until parent has finished its work: read child's pid from
572575
* parent's stack, and check, if bad result.
@@ -581,7 +584,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
581584

582585
wait_stub_done(pid);
583586

584-
pid = data->err;
587+
pid = data->parent_err;
585588
if (pid < 0) {
586589
printk(UM_KERN_ERR "copy_context_skas0 - stub-parent reports "
587590
"error %d\n", -pid);
@@ -593,10 +596,10 @@ int copy_context_skas0(unsigned long new_stack, int pid)
593596
* child's stack and check it.
594597
*/
595598
wait_stub_done(pid);
596-
if (child_data->err != STUB_DATA) {
597-
printk(UM_KERN_ERR "copy_context_skas0 - stub-child reports "
598-
"error %ld\n", child_data->err);
599-
err = child_data->err;
599+
if (child_data->child_err != STUB_DATA) {
600+
printk(UM_KERN_ERR "copy_context_skas0 - stub-child %d reports "
601+
"error %ld\n", pid, data->child_err);
602+
err = data->child_err;
600603
goto out_kill;
601604
}
602605

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static inline void remap_stack(int fd, unsigned long offset)
8686
"d" (PROT_READ | PROT_WRITE),
8787
"S" (MAP_FIXED | MAP_SHARED), "D" (fd),
8888
"a" (offset),
89-
"i" (&((struct stub_data *) STUB_DATA)->err)
89+
"i" (&((struct stub_data *) STUB_DATA)->child_err)
9090
: "memory");
9191
}
9292

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static inline void remap_stack(long fd, unsigned long offset)
9292
"d" (PROT_READ | PROT_WRITE),
9393
"g" (MAP_FIXED | MAP_SHARED), "g" (fd),
9494
"g" (offset),
95-
"i" (&((struct stub_data *) STUB_DATA)->err)
95+
"i" (&((struct stub_data *) STUB_DATA)->child_err)
9696
: __syscall_clobber, "r10", "r8", "r9" );
9797
}
9898

0 commit comments

Comments
 (0)