[PATCH] MDEV-26645: Fix UB in Item_func_plus and Item_func_minus
authorMarko Mäkelä <marko.makela@mariadb.com>
Fri, 18 Feb 2022 14:31:54 +0000 (16:31 +0200)
committerOtto Kekäläinen <otto@debian.org>
Thu, 10 Mar 2022 06:26:32 +0000 (06:26 +0000)
An integer overflow in an expression like a+b or a-b is undefined behavior.
The compiler is allowed to assume that no such overflow is possible,
and optimize away some code accordingly.

Item_func_plus::int_op(), Item_func_minus::int_op(): Always check
for overflow.

Depending on the compiler and the compilation options, a test might fail:

CURRENT_TEST: main.func_math
mysqltest: At line 425: query 'SELECT 9223372036854775807 + 9223372036854775807' succeeded - should have failed with errno 1690...

A similar bug had been fixed earlier in
commit 328edf8560dbf1941ce314fa112e0db05d9f97f1.

This commit was backported from MariaDB 10.9 to Debian with MariaDB 10.6.

Gbp-Pq: Name MDEV-26645-fix-test-main.func_math.patch

sql/item_func.cc

index ed49733d15da03080fb9ccd558bccf8e842c7427..92f6255d958b4e4a3b2f57d689a9eecc7a5451ec 100644 (file)
@@ -1,5 +1,5 @@
 /* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
-   Copyright (c) 2009, 2021, MariaDB
+   Copyright (c) 2009, 2022, MariaDB
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -1156,14 +1156,10 @@ longlong Item_func_plus::int_op()
     }
   }
 
-#ifndef WITH_UBSAN
-  res= val0 + val1;
-#else
   if (res_unsigned)
     res= (longlong) ((ulonglong) val0 + (ulonglong) val1);
   else
-    res= val0+val1;
-#endif /* WITH_UBSAN */
+    res= val0 + val1;
 
   return check_integer_overflow(res, res_unsigned);
 
@@ -1326,14 +1322,10 @@ longlong Item_func_minus::int_op()
         goto err;
     }
   }
-#ifndef WITH_UBSAN
-  res= val0 - val1;
-#else
   if (res_unsigned)
     res= (longlong) ((ulonglong) val0 - (ulonglong) val1);
   else
     res= val0 - val1;
-#endif /* WITH_UBSAN */
 
   return check_integer_overflow(res, res_unsigned);