[Toybox] 回复: sh: run "command &" in background, showing "jobs" or "ps" will crash

Rob Landley rob at landley.net
Thu Jun 1 19:36:32 PDT 2023


On 5/30/23 20:56, Mingliang HU 胡明亮 wrote:
>> >       pplist = 0;
>> 
>> Assigning zero to it there should make the free() be a NOP?
>> 
>> > }
>> >
>> >
>> > Then, in show_job(), it will use random points.
>> 
>> I believe you, but need a reproduction sequence.
> 
> I failed to reproduce the crash on linux although the "jobs" result is not correct. 
> In my used OS, I can find TT.jobs.v[arg->c++] = pplist which has an particular address. 
> Then pplist = 0 soon. But TT.jobs.v[arg->c++] keeps that previous particular address. 
> This particular address would be allocated by other OS process again.

The real question is what freed it? pplist = 0 should prevent free(pplist) from
applying.

What OS are you running it on? (I know it's been ported to qnx...)

> Then in show_jobs(), TT.jobs.v[i]->arg.v will access wrong memory. 

I should probably fill in the rest of the jobs plumbing now it's got a user
waiting for it. At the time the issue was working out object lifetimes.

When job control is active, the shell needs a SIGCHLD handler record the exit
status of child processes in the jobs table, but the jobs table doesn't get
FLUSHED until you do a "wait". The crazy part is that you MUST do a wait with no
arguments to flush the jobs table. Neither wait $PID nor wait -n will do so:

$ exit 42 &
[1] 7534
$ wait 7534
[1]+  Exit 42                 exit 42
$ echo $?
42
$ wait 7534
$ echo $?
42
$ wait -n
$ echo $?
127
$ wait 7534
$ echo $?
42
$ wait
$ wait 7534
bash: wait: pid 7534 is not a child of this shell

That's why it wound up in the unfinished bucket, because the semantics were
nonobvious and I parked it while working them out...

> "snprintf" will use "strlen" to access a quite a long "string" without "\0" and crash.

Once you've got a use-after-free error, further details are just tracking the
flying shrapnel after the initial collision. The PROBLEM is this memory got
freed but is still pointed to in the jobs table. One of the two is wrong.

Rob


More information about the Toybox mailing list