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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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 
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...

...
(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
(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) 



[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux