Blame SOURCES/0001-Fix-CVE-2016-2315-CVE-2016-2324.patch

647f52
From 73b65b02d5d1aa4612bb7015f80c8cd1b5e828cd Mon Sep 17 00:00:00 2001
647f52
From: Petr Stodulka <pstodulk@redhat.com>
647f52
Date: Fri, 18 Mar 2016 17:14:32 +0100
647f52
Subject: [PATCH] Fix CVE-2016-2315 CVE-2016-2324
647f52
647f52
- added upstream macros for detecting size_t overflow (much more just
647f52
  for easier related changes in future, if we want to do some yet)
647f52
- upstream solution removes function path_name() and modify all related
647f52
  part of code to replace this function. However, it's too hard for
647f52
  backport to such old version of git without unchanged behaviour,
647f52
  so application just die with error message instead.
647f52
---
647f52
 diff.h            |  4 ++--
647f52
 git-compat-util.h | 35 +++++++++++++++++++++++++++++++++++
647f52
 revision.c        | 13 ++++++++++---
647f52
 3 files changed, 47 insertions(+), 5 deletions(-)
647f52
647f52
diff --git a/diff.h b/diff.h
647f52
index ce123fa..88db230 100644
647f52
--- a/diff.h
647f52
+++ b/diff.h
647f52
@@ -209,8 +209,8 @@ struct combine_diff_path {
647f52
 	} parent[FLEX_ARRAY];
647f52
 };
647f52
 #define combine_diff_path_size(n, l) \
647f52
-	(sizeof(struct combine_diff_path) + \
647f52
-	 sizeof(struct combine_diff_parent) * (n) + (l) + 1)
647f52
+	st_add4(sizeof(struct combine_diff_path), (l), 1, \
647f52
+		st_mult(sizeof(struct combine_diff_parent), (n)))
647f52
 
647f52
 extern void show_combined_diff(struct combine_diff_path *elem, int num_parent,
647f52
 			      int dense, struct rev_info *);
647f52
diff --git a/git-compat-util.h b/git-compat-util.h
647f52
index d493a8c..d5a15fa 100644
647f52
--- a/git-compat-util.h
647f52
+++ b/git-compat-util.h
647f52
@@ -46,6 +46,14 @@
647f52
 #define unsigned_add_overflows(a, b) \
647f52
     ((b) > maximum_unsigned_value_of_type(a) - (a))
647f52
 
647f52
+/*
647f52
+ * Returns true if the multiplication of "a" and "b" will
647f52
+ * overflow. The types of "a" and "b" must match and must be unsigned.
647f52
+ * Note that this macro evaluates "a" twice!
647f52
+ */
647f52
+#define unsigned_mult_overflows(a, b) \
647f52
+    ((a) && (b) > maximum_unsigned_value_of_type(a) / (a))
647f52
+
647f52
 #ifdef __GNUC__
647f52
 #define TYPEOF(x) (__typeof__(x))
647f52
 #else
647f52
@@ -526,6 +534,33 @@ extern void release_pack_memory(size_t);
647f52
 typedef void (*try_to_free_t)(size_t);
647f52
 extern try_to_free_t set_try_to_free_routine(try_to_free_t);
647f52
 
647f52
+static inline size_t st_add(size_t a, size_t b)
647f52
+{
647f52
+	if (unsigned_add_overflows(a, b))
647f52
+		die("size_t overflow: %"PRIuMAX" + %"PRIuMAX,
647f52
+		    (uintmax_t)a, (uintmax_t)b);
647f52
+	return a + b;
647f52
+}
647f52
+#define st_add3(a,b,c)   st_add((a),st_add((b),(c)))
647f52
+#define st_add4(a,b,c,d) st_add((a),st_add3((b),(c),(d)))
647f52
+
647f52
+static inline size_t st_mult(size_t a, size_t b)
647f52
+{
647f52
+	if (unsigned_mult_overflows(a, b))
647f52
+		die("size_t overflow: %"PRIuMAX" * %"PRIuMAX,
647f52
+		    (uintmax_t)a, (uintmax_t)b);
647f52
+	return a * b;
647f52
+}
647f52
+
647f52
+static inline size_t st_sub(size_t a, size_t b)
647f52
+{
647f52
+	if (a < b)
647f52
+		die("size_t underflow: %"PRIuMAX" - %"PRIuMAX,
647f52
+		    (uintmax_t)a, (uintmax_t)b);
647f52
+	return a - b;
647f52
+}
647f52
+
647f52
+
647f52
 extern char *xstrdup(const char *str);
647f52
 extern void *xmalloc(size_t size);
647f52
 extern void *xmallocz(size_t size);
647f52
diff --git a/revision.c b/revision.c
647f52
index f40ccf1..b897ca6 100644
647f52
--- a/revision.c
647f52
+++ b/revision.c
647f52
@@ -24,16 +24,21 @@ char *path_name(const struct name_path *path, const char *name)
647f52
 {
647f52
 	const struct name_path *p;
647f52
 	char *n, *m;
647f52
-	int nlen = strlen(name);
647f52
-	int len = nlen + 1;
647f52
+	size_t nlen = strlen(name);
647f52
+	size_t len = st_add(nlen, 1);
647f52
+
647f52
+	if(len >= INT_MAX)
647f52
+		die("path_name(): path is too long.");
647f52
 
647f52
 	for (p = path; p; p = p->up) {
647f52
 		if (p->elem_len)
647f52
 			len += p->elem_len + 1;
647f52
+			if(len >= INT_MAX)
647f52
+				die("path_name(): path is too long.");
647f52
 	}
647f52
 	n = xmalloc(len);
647f52
 	m = n + len - (nlen + 1);
647f52
-	strcpy(m, name);
647f52
+	memcpy(m, name, nlen + 1);
647f52
 	for (p = path; p; p = p->up) {
647f52
 		if (p->elem_len) {
647f52
 			m -= p->elem_len + 1;
647f52
-- 
647f52
2.4.3
647f52