Author: mav Date: Wed Mar 6 19:37:38 2013 New Revision: 247898 URL: http://svnweb.freebsd.org/changeset/base/247898
Log: Fix time math overflows and improve zero intervals handling in poll(), select(), nanosleep() and kevent() functions after calloutng changes. Reported by: bde Modified: head/sys/kern/kern_event.c head/sys/kern/kern_time.c head/sys/kern/sys_generic.c Modified: head/sys/kern/kern_event.c ============================================================================== --- head/sys/kern/kern_event.c Wed Mar 6 18:45:11 2013 (r247897) +++ head/sys/kern/kern_event.c Wed Mar 6 19:37:38 2013 (r247898) @@ -1329,11 +1329,16 @@ kqueue_scan(struct kqueue *kq, int maxev goto done_nl; } if (timespecisset(tsp)) { - rsbt = tstosbt(*tsp); - if (TIMESEL(&asbt, rsbt)) - asbt += tc_tick_sbt; - asbt += rsbt; - rsbt >>= tc_precexp; + if (tsp->tv_sec < INT32_MAX) { + rsbt = tstosbt(*tsp); + if (TIMESEL(&asbt, rsbt)) + asbt += tc_tick_sbt; + asbt += rsbt; + if (asbt < rsbt) + asbt = 0; + rsbt >>= tc_precexp; + } else + asbt = 0; } else asbt = -1; } else Modified: head/sys/kern/kern_time.c ============================================================================== --- head/sys/kern/kern_time.c Wed Mar 6 18:45:11 2013 (r247897) +++ head/sys/kern/kern_time.c Wed Mar 6 19:37:38 2013 (r247898) @@ -484,13 +484,20 @@ kern_nanosleep(struct thread *td, struct { struct timespec ts; sbintime_t sbt, sbtt, prec, tmp; + time_t over; int error; if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000) return (EINVAL); if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0)) return (0); - tmp = tstosbt(*rqt); + ts = *rqt; + if (ts.tv_sec > INT32_MAX / 2) { + over = ts.tv_sec - INT32_MAX / 2; + ts.tv_sec -= over; + } else + over = 0; + tmp = tstosbt(ts); prec = tmp; prec >>= tc_precexp; if (TIMESEL(&sbt, tmp)) @@ -504,6 +511,7 @@ kern_nanosleep(struct thread *td, struct TIMESEL(&sbtt, tmp); if (rmt != NULL) { ts = sbttots(sbt - sbtt); + ts.tv_sec += over; if (ts.tv_sec < 0) timespecclear(&ts); *rmt = ts; Modified: head/sys/kern/sys_generic.c ============================================================================== --- head/sys/kern/sys_generic.c Wed Mar 6 18:45:11 2013 (r247897) +++ head/sys/kern/sys_generic.c Wed Mar 6 19:37:38 2013 (r247898) @@ -1051,12 +1051,19 @@ kern_select(struct thread *td, int nd, f error = EINVAL; goto done; } - rsbt = tvtosbt(rtv); - precision = rsbt; - precision >>= tc_precexp; - if (TIMESEL(&asbt, rsbt)) - asbt += tc_tick_sbt; - asbt += rsbt; + if (rtv.tv_sec == 0 && rtv.tv_usec == 0) + asbt = 0; + else if (rtv.tv_sec < INT32_MAX) { + rsbt = tvtosbt(rtv); + precision = rsbt; + precision >>= tc_precexp; + if (TIMESEL(&asbt, rsbt)) + asbt += tc_tick_sbt; + asbt += rsbt; + if (asbt < rsbt) + asbt = -1; + } else + asbt = -1; } else asbt = -1; seltdinit(td); @@ -1295,12 +1302,16 @@ sys_poll(td, uap) error = EINVAL; goto done; } - rsbt = SBT_1MS * uap->timeout; - precision = rsbt; - precision >>= tc_precexp; - if (TIMESEL(&asbt, rsbt)) - asbt += tc_tick_sbt; - asbt += rsbt; + if (uap->timeout == 0) + asbt = 0; + else { + rsbt = SBT_1MS * uap->timeout; + precision = rsbt; + precision >>= tc_precexp; + if (TIMESEL(&asbt, rsbt)) + asbt += tc_tick_sbt; + asbt += rsbt; + } } else asbt = -1; seltdinit(td); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"