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) |

Reply via email to