mpatch: introduce a safeadd() helper to work around UB int overflow stable
authorAugie Fackler <augie@google.com>
Mon, 30 Apr 2018 22:13:42 -0400
branchstable
changeset 38190 1ec4cb8cbc87
parent 38189 faa924469635
child 38191 b8b253aec953
mpatch: introduce a safeadd() helper to work around UB int overflow We're about to make extensive use of this. This change duplicates some stdbool.h portability hacks from cext/util.h. We should probably clean that up in the future, but we'll skip that for now in order to make security backports easier.
mercurial/mpatch.c
--- a/mercurial/mpatch.c	Sat Apr 28 10:09:12 2018 -0400
+++ b/mercurial/mpatch.c	Mon Apr 30 22:13:42 2018 -0400
@@ -20,6 +20,7 @@
  of the GNU General Public License, incorporated herein by reference.
 */
 
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -27,6 +28,15 @@
 #include "compat.h"
 #include "mpatch.h"
 
+/* VC9 doesn't include bool and lacks stdbool.h based on cext/util.h */
+#if defined(_MSC_VER) || __STDC_VERSION__ < 199901L
+#define true 1
+#define false 0
+typedef unsigned char bool;
+#else
+#include <stdbool.h>
+#endif
+
 static struct mpatch_flist *lalloc(ssize_t size)
 {
 	struct mpatch_flist *a = NULL;
@@ -60,6 +70,24 @@
 	return a->tail - a->head;
 }
 
+/* add helper to add src and *dest iff it won't overflow */
+static inline bool safeadd(int src, int *dest)
+{
+	if ((src > 0) == (*dest > 0)) {
+		if (*dest > 0) {
+			if (src > (INT_MAX - *dest)) {
+				return false;
+			}
+		} else {
+			if (src < (INT_MIN - *dest)) {
+				return false;
+			}
+		}
+	}
+	*dest += src;
+	return true;
+}
+
 /* move hunks in source that are less cut to dest, compensating
    for changes in offset. the last hunk may be split if necessary.
 */