Re: PATCH for 2.2-pre: poll timeout (was Re: Serious bug)

Alan Modra (alan@spri.levels.unisa.edu.au)
Mon, 11 Jan 1999 15:07:43 +1030 (CST)


On Sun, 10 Jan 1999, Chip Salzenberg wrote:
A neater solution than the one I posted, but still having holes..

> According to Jes Sorensen:
> > schedule_timeout: wrong timeout value f3333335 from 00024c0e
> >
> > I looked up where address 00024c0e was, it turned out to be do_poll() in
> > fs/select.c
> > timeout = (timeout*HZ+999)/1000+1;
> > which obviously overflows with a timeout like this. The resulting value
> > in my case is 0xf3333335...
>
> I agree with your analysis. I'm now running with the below patch.
> (I decided to look into this because I use mutt. :-))

Maybe this is a nitpick, but consider what happens with timeout=MAXLONG
(actually 1000/HZ-1 values up to MAXLONG). The macro is
#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
so for timeout==MAXLONG, HZ==100, the numerator evaluates as MAXLONG+9,
which is negative.

This is a problem with other occurences of the ROUND_UP macro too.

The easy fix is to cast to unsigned long
timeout = ROUND_UP((unsigned long)timeout, 1000/HZ);

> Index: fs/select.c
> *************** asmlinkage int sys_poll(struct pollfd *
> *** 335,339 ****
> timeout = MAX_SCHEDULE_TIMEOUT;
> else if (timeout)
> ! timeout = (timeout*HZ+999)/1000+1;
>
> err = -ENOMEM;
> --- 335,339 ----
> timeout = MAX_SCHEDULE_TIMEOUT;
> else if (timeout)
> ! timeout = ROUND_UP(timeout, 1000/HZ);
>
> err = -ENOMEM;
>

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/