Module Name: src Committed By: kamil Date: Sun Jul 8 14:42:52 UTC 2018
Modified Files: src/sys/kern: kern_timeout.c Log Message: Try to avoid signed integer overflow in callout_softclock() The delta operation (c->c_time - ticks) is documented as safe, however it still can cause overflow in narrow case scenarios. Try to avoid overflow/underflow or at least make it less frequent with a direct comparison of c->c_time and tics. Perform the operation of subtraction only when c->c_time > ticks. sys/kern/kern_timeout.c:720:9, signed integer overflow: -2147410738 - 72912 cannot be represented in type 'int' Detected with Kernel Undefined Behavior Sanitizer. Patch suggested by <Riastradh> To generate a diff of this commit: cvs rdiff -u -r1.54 -r1.55 src/sys/kern/kern_timeout.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_timeout.c diff -u src/sys/kern/kern_timeout.c:1.54 src/sys/kern/kern_timeout.c:1.55 --- src/sys/kern/kern_timeout.c:1.54 Tue Jan 16 08:15:29 2018 +++ src/sys/kern/kern_timeout.c Sun Jul 8 14:42:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_timeout.c,v 1.54 2018/01/16 08:15:29 ozaki-r Exp $ */ +/* $NetBSD: kern_timeout.c,v 1.55 2018/07/08 14:42:52 kamil Exp $ */ /*- * Copyright (c) 2003, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.54 2018/01/16 08:15:29 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.55 2018/07/08 14:42:52 kamil Exp $"); /* * Timeouts are kept in a hierarchical timing wheel. The c_time is the @@ -717,12 +717,12 @@ callout_softclock(void *v) /* If due run it, otherwise insert it into the right bucket. */ ticks = cc->cc_ticks; - delta = c->c_time - ticks; - if (delta > 0) { + if (c->c_time > ticks) { + delta = c->c_time - ticks; CIRCQ_INSERT(&c->c_list, BUCKET(cc, delta, c->c_time)); continue; } - if (delta < 0) + if (c->c_time < ticks) cc->cc_ev_late.ev_count++; c->c_flags = (c->c_flags & ~CALLOUT_PENDING) |