[Bug 12236] ash hangs after wait returns EINTR
bugzilla at busybox.net
bugzilla at busybox.net
Tue Oct 8 14:06:35 UTC 2019
https://bugs.busybox.net/show_bug.cgi?id=12236
--- Comment #2 from Denys Vlasenko <vda.linux at googlemail.com> ---
Yes, looks like the bug is here:
/*
* If we were from a system call, check for system call restarting...
*/
if (regs->orig_r2 >= 0) {
continue_addr = regs->ea;
restart_addr = continue_addr - 4;
retval = regs->r2;
/*
* Prepare for system call restart. We do this here so that a
* debugger will see the already changed PC.
*/
switch (retval) {
case ERESTART_RESTARTBLOCK:
restart = -2;
case ERESTARTNOHAND:
case ERESTARTSYS:
case ERESTARTNOINTR:
restart++;
regs->r2 = regs->orig_r2;
regs->r7 = regs->orig_r7;
regs->ea = restart_addr;
break;
}
}
The above code examines r2, the "errno" register on the exit from syscall, but
it DOES NOT check that it is indeed an error!
linux/arch/nios2/kernel/entry.S says:
/* Execute the system call */
callr r1
/* If the syscall returns a negative result:
* Set r7 to 1 to indicate error,
* Negate r2 to get a positive error code
* If the syscall returns zero or a positive value:
* Set r7 to 0.
* The sigreturn system calls will skip the code below by
* adding to register ra. To avoid destroying registers
*/
translate_rc_and_ret:
movi r1, 0
bge r2, zero, 3f
sub r2, zero, r2
movi r1, 1
3:
IOW: the code in do_signal() should have checked that r7 == 1 before assuming
that r2 == 512 means "ERESTARTSYS".
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the busybox-cvs
mailing list