[Toybox] sleep overflow
Rob Landley
rob at landley.net
Fri Aug 17 17:04:06 PDT 2012
On 08/15/2012 07:48 AM, Elie De Brauwer wrote:
> Hello all,
>
> Found a little bug in sleep, for insanely large values (so insane people
> might use them to sleep forever and they will be disappointed when
> forever means zero) sleep might return immediately ( config SLEEP_FLOAT
> is impact, config SLEEP and config USLEEP are not affected).
>
> Now sleep (with floating point support) functions as follows:
>
> edb at lapedb:~/edb-stuff/toybox/toybox$ strace -e nanosleep ./toybox
> sleep 24855d
> nanosleep({2147472000, 0}, ^C <unfinished ...>
> edb at lapedb:~/edb-stuff/toybox/toybox$ strace -e nanosleep ./toybox
> sleep 24856d
> nanosleep({2147558400, 2147483648}, NULL) = -1 EINVAL (Invalid argument)
>
> So it'd better not sleep longer than 68 years :D.
Your patch is actually a workaround for a glibc bug. On uClibc:
$ strace ./toybox sleep 24855d
execve("./toybox", ["./toybox", "sleep", "24855d"], [/* 37 vars */]) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo
...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo
...}) = 0
umask(0) = 022
umask(022) = 0
brk(0) = 0x24c1000
brk(0x24c2000) = 0x24c2000
umask(0) = 022
umask(022) = 0
nanosleep({2147472000, 0},
And it sits there.
> This is caused by an overflow in the argument parsing, if it exceeds
> INT_MAX (0x80000000 on 32 bit) nanosleep will start to consider certain
> variables as negative.
Actually the overflow is being caught, the problem is that glibc is then
maxing out the nanoseconds field, and the kernel only accepts a certain
maximum value in the nanoseconds before barfing. (You should never
_need_ to specify more than 1 billion in there, because that's what the
seconds field is for.)
> I've attached a patch which just tops this off
> to INT_MAX. With it, it behaves more or less as 'real' sleep:
>
> edb at lapedb:~/edb-stuff/toybox/toybox$ strace -e nanosleep ./toybox
> sleep 24856d
> nanosleep({2147483647, 0}, ^C <unfinished ...>
Ooh, decisions, decisions.
Anybody know how bionic or musl handles this? (I need to finish
migrating to my new nebook so I have space to set up test environments.
This old netbook only has 3 gigs free.)
In _theory_ time_t is a long for a reason. In practice, 60 year waits
might as well be "forever"...
Rob
--
GNU/Linux isn't: Linux=GPLv2, GNU=GPLv3+, they can't share code.
Either it's "mere aggregation", or a license violation. Pick one.
More information about the Toybox
mailing list