Module Name:    src
Committed By:   kamil
Date:           Wed Jun 27 17:12:50 UTC 2018

Modified Files:
        src/bin/expr: expr.y

Log Message:
Improve the * operator handling in expr(1)

Fixes overflow detection in expressions INT * -UINT.

Detected with libFuzzer & UBSan.


To generate a diff of this commit:
cvs rdiff -u -r1.43 -r1.44 src/bin/expr/expr.y

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/expr/expr.y
diff -u src/bin/expr/expr.y:1.43 src/bin/expr/expr.y:1.44
--- src/bin/expr/expr.y:1.43	Thu Jun 14 02:46:56 2018
+++ src/bin/expr/expr.y	Wed Jun 27 17:12:49 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: expr.y,v 1.43 2018/06/14 02:46:56 christos Exp $ */
+/* $NetBSD: expr.y,v 1.44 2018/06/27 17:12:49 kamil Exp $ */
 
 /*_
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 %{
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: expr.y,v 1.43 2018/06/14 02:46:56 christos Exp $");
+__RCSID("$NetBSD: expr.y,v 1.44 2018/06/27 17:12:49 kamil Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -351,17 +351,27 @@ perform_arith_op(const char *left, const
 		 * Check for over-& underflow.
 		 */
 
-		/* Simplify the conditions */
+		/*
+		 * Simplify the conditions:
+		 *  - remove the case of both negative arguments
+		 *    unless the operation will cause an overflow
+		 */
 		if (l < 0 && r < 0 && l != INT64_MIN && r != INT64_MIN) {
 			l = -l;
 			r = -r;
 		}
 
+		/* - remove the case of legative l and positive r */
+		if (l < 0 && r >= 0) {
+			/* Use res as a temporary variable */
+			res = l;
+			l = r;
+			r = res;
+		}
+
 		if ((l < 0 && r < 0) ||
-		    ((l != 0 && r != 0) &&
-		     (((l > 0 && r > 0) && (l > INT64_MAX / r)) ||
-		     ((((l < 0 && r > 0) || (l > 0 && r < 0)) &&
-		      (r != -1 && (l < INT64_MIN / r))))))) {
+		    (r > 0 && l > INT64_MAX / r) ||
+		    (r <= 0 && r < INT64_MIN / l)) {
 			yyerror("integer overflow or underflow occurred for "
 			    "operation '%s %s %s'", left, op, right);
 			/* NOTREACHED */

Reply via email to