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

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