Re: core dump analysis, was Re: stack smashing detected

Michael Schmitz <[email protected]>
Newsgroups gmane.linux.ports.m68k,gmane.linux.debian.ports.68k
Message-ID <[email protected]>
Hi Finn,

On 2/04/23 22:46, Finn Thain wrote:
> On Sat, 1 Apr 2023, Andreas Schwab wrote:
>
>> On Apr 01 2023, Finn Thain wrote:
>>
>>> So, in summary, the canary validation failed in this case not because
>>> the canary got clobbered but because %a3 got clobbered, somewhere
>>> between __wait3+24 and __wait3+70 (below).
>>>
>>> The call to __GI___wait4_time64 causes %a3 to be saved to and restored
>>> from the stack, so stack corruption seems to be a strong possibility
>>> to explain the change in %a3.
>>>
>>> But if that's what happened, I'd expect __GI___wait4_time64 to report
>>> stack smashing, not __wait3...
>> The stask smashing probably didn't fire in __wait4_time64, because it
>> hit the saved register area, not the canary (which reside on the
>> opposite ends of the stack frame).
>>
> OK.
>
> This is odd:
>
> https://sources.debian.org/src/dash/0.5.12-2/src/jobs.c/?hl=1165#L1165
>
>    1176          do {
>    1177                  gotsigchld = 0;
>    1178                  do
>    1179                          err = wait3(status, flags, NULL);
>    1180                  while (err < 0 && errno == EINTR);
>    1181
>    1182                  if (err || (err = -!block))
>    1183                          break;
>    1184
>    1185                  sigblockall(&oldmask);
>    1186
>    1187                  while (!gotsigchld && !pending_sig)
>    1188                          sigsuspend(&oldmask);
>    1189
>    1190                  sigclearmask();
>    1191          } while (gotsigchld);
>    1192
>    1193  return err;
>
> Execution of dash under gdb doesn't seem to agree with the source code
> above.
>
> If wait3() returns the child pid then the break should execute. And it
> does return the pid (4107) but the while loop was not terminated. Hence
> wait3() was called again and the same breakpoint was hit again. Also, the

I wonder whether line 1182 got miscompiled by gcc. As err == 4107 it's > 
0 and the break clearly ought to have been taken, and the second 
condition (which changes err) does not need to be examined.  Do the same 
ordering constraints apply to '||' as to '&&' ?

What does the disassembly of this section look like?

> while loop should have ended after the first iteration because gotsigchild
> should have been set by the signal handler which executed before wait3()
> even returned...

Setting gotsigchild > 0 would cause the while loop to continue, no?

The second wait3 call then returns an error (errno ECHILD), leaves 
gotsigchild clear and exits the loop (returning from waitproc with 
error, which it shouldn't have).

>
> ...
> (gdb) c
> Continuing.
> #
> #
> # x=$(:)
> [Detaching after fork from child process 4107]
>
> Program received signal SIGCHLD, Child status changed.
> 0xc00e81b6 in __GI___wait4_time64 (pid=-1, stat_loc=0xeffff87a, options=2,
>      usage=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:35
> 35      ../sysdeps/unix/sysv/linux/wait4.c: No such file or directory.
> (gdb) c
> Continuing.
>
> Breakpoint 3, waitproc (status=0xeffff86a, block=1) at jobs.c:1180
> 1180    jobs.c: No such file or directory.
> (gdb) info locals
> oldmask = {__val = {1101825, 3844132865, 2072969216, 192511, 4190371840,
>      4509697, 3836788738, 1049415681, 3837317121, 3094671359, 4184080384,
>      536870943, 717475840, 3485913089, 3836792833, 2072969216, 184321,
>      3844141055, 4190425089, 4127248385, 3094659084, 597610497, 4137734145,
>      3844079616, 131072, 269156352, 184320, 3878473729, 3844132865, 3094663168,
>      3549089793, 3844132865}}
> flags = 2
> err = 4107
> oldmask = <optimized out>
> flags = <optimized out>
> err = <optimized out>
> (gdb) print errno
> $6 = 2

Is that ENOENT the returned status from the child process?

Cheers,

     Michael

> (gdb) c
> Continuing.
>
> Breakpoint 3, waitproc (status=0xeffff86a, block=0) at jobs.c:1180
> 1180    in jobs.c
> (gdb) info locals
> oldmask = {__val = {1101825, 3844132865, 2072969216, 192511, 4190371840,
>      4509697, 3836788738, 1049415681, 3837317121, 3094671359, 4184080384,
>      536870943, 717475840, 3485913089, 3836792833, 2072969216, 184321,
>      3844141055, 4190425089, 4127248385, 3094659084, 597610497, 4137734145,
>      3844079616, 131072, 269156352, 184320, 3878473729, 3844132865, 3094663168,
>      3549089793, 3844132865}}
> flags = 3
> err = -1
> oldmask = <optimized out>
> flags = <optimized out>
> err = <optimized out>
> (gdb) print errno
> $7 = 10
> (gdb)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.