Bugs in coreutils/timeout.c for systems without MMU
Patrick Hock
patrickrhock at gmail.com
Thu Feb 29 01:47:58 UTC 2024
Hi,
consider the example prompt for timeout below:
timeout -s 9 1 sleep 5
In timeout.c line 120-123:
#if !BB_MMU
argv[optind] = xasprintf("-p%u", parent);
argv[optind + 1] = NULL;
#endif
This puts a -p:PID argument at the end of the timeout command when it is
re-execed, like this example:
timeout -s 9 1 -p:577
(Note the lack of a argument after the timeout in seconds (1), this is part
of another bug I'll address later.)
The issue is that the way options are parsed with getopt32 at the beginning
of the program, the '+' makes getopt32 stop parsing when it gets to the
first non-option argument (which happens to be the timeout in seconds).
This means when timeout is re-execed with the -p option at the end, the -p
option is never parsed. This is important because on line 109, the presence
of the -p option should make parent true, but it never will.
The solution I propose to this is to put the -p option BEFORE the timeout
in seconds, essentially swapping the position of the two so that the -p
precedes any non option arguments and will be parsed by getopt32
So that would be:
#if !BB_MMU
argv[optind] = argv[optind - 1]
argv[optind - 1] = xasprintf("-p%u", parent);
argv[optind + 1] = NULL;
#endif
Also, when timeout is re-execed with the -p option, you no longer need to
pass in an argument for what program needs to be executed. Timeout just
needs to kill the process specified by -p after the given timeout. So, on
line 98-99:
if (!argv[optind]) /* no PROG? */
bb_show_usage();
This should be put after the branch goto grandchild on line 110.
Since bb_daemonize_or_rexec redirects output of the re-execed timeout
(without a program argument) to /dev/null, you won't see the usage prompt
printed to the terminal, but effectively timeout won't work because it's
killed prematurely by this.
Also, I'm not sure if it is intentional, but this implementation makes it
possible to pass a -p:PID argument to timeout in the command line, which
makes it kill the specified process ID after the timeout elapses.
Patrick H
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.busybox.net/pipermail/busybox/attachments/20240228/7b869075/attachment-0001.html>
More information about the busybox
mailing list