diff mercurial/cext/revlog.c @ 40812:9cdd525d97b2 stable

revlog: fix out-of-bounds access by negative parents read from revlog (SEC) 82d6a35cf432 wasn't enough. Several callers don't check negative revisions but for -1 (nullrev), which would directly lead to out-of-bounds read, and buffer overflow could follow. RCE might be doable with carefully crafted revlog structure, though I don't think this would be useful attack surface.
author Yuya Nishihara <yuya@tcha.org>
date Thu, 01 Nov 2018 20:32:59 +0900
parents a91a2837150b
children 884321cd26c3
line wrap: on
line diff
--- a/mercurial/cext/revlog.c	Mon Dec 03 11:14:44 2018 -0800
+++ b/mercurial/cext/revlog.c	Thu Nov 01 20:32:59 2018 +0900
@@ -157,6 +157,12 @@
 	return (const char *)(self->buf.buf) + pos * v1_hdrsize;
 }
 
+/*
+ * Get parents of the given rev.
+ *
+ * The specified rev must be valid and must not be nullrev. A returned
+ * parent revision may be nullrev, but is guaranteed to be in valid range.
+ */
 static inline int index_get_parents(indexObject *self, Py_ssize_t rev,
 				    int *ps, int maxrev)
 {
@@ -171,7 +177,7 @@
 	}
 	/* If index file is corrupted, ps[] may point to invalid revisions. So
 	 * there is a risk of buffer overflow to trust them unconditionally. */
-	if (ps[0] > maxrev || ps[1] > maxrev) {
+	if (ps[0] < -1 || ps[0] > maxrev || ps[1] < -1 || ps[1] > maxrev) {
 		PyErr_SetString(PyExc_ValueError, "parent out of range");
 		return -1;
 	}