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 */