# HG changeset patch
# User Yuya Nishihara <y...@tcha.org>
# Date 1540729744 -32400
#      Sun Oct 28 21:29:04 2018 +0900
# Branch stable
# Node ID 28a5ec244ba88ce4a46a26a32c24fa36f7597245
# Parent  2af0076a5465be08dc2dc91e352abfbbe9c2ab17
rust: fix possible out-of-bounds read through index_get_parents()

index_get_parents() is an internal function, which doesn't check if the
specified rev is valid. If rustlazyancestors() were instantiated with an
invalid stoprev, it would access to invalid memory region.

diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -2308,7 +2308,7 @@ struct rustlazyancestorsObjectStruct {
 /* FFI exposed from Rust code */
 rustlazyancestorsObject *rustlazyancestors_init(
        indexObject *index,
-       /* to pass index_get_parents() */
+       /* to pass index_get_parents_checked() */
        int (*)(indexObject *, Py_ssize_t, int*, int),
        /* intrevs vector */
        Py_ssize_t initrevslen, long *initrevs,
@@ -2318,6 +2318,16 @@ void rustlazyancestors_drop(rustlazyance
 int rustlazyancestors_next(rustlazyancestorsObject *self);
 int rustlazyancestors_contains(rustlazyancestorsObject *self, long rev);
 
+static int index_get_parents_checked(indexObject *self, Py_ssize_t rev,
+                                     int *ps, int maxrev)
+{
+       if (rev < 0 || rev >= index_length(self)) {
+               PyErr_SetString(PyExc_ValueError, "rev out of range");
+               return -1;
+       }
+       return index_get_parents(self, rev, ps, maxrev);
+}
+
 /* CPython instance methods */
 static int rustla_init(rustlazyancestorsObject *self,
                        PyObject *args) {
@@ -2358,12 +2368,13 @@ static int rustla_init(rustlazyancestors
                goto bail;
 
        self->iter = rustlazyancestors_init(index,
-                                           index_get_parents,
+                                           index_get_parents_checked,
                                            linit, initrevs,
                                            stoprev, inclusive);
        if (self->iter == NULL) {
                /* if this is because of GraphError::ParentOutOfRange
-                * index_get_parents() has already set the proper ValueError */
+                * index_get_parents_checked() has already set the proper
+                * ValueError */
                goto bail;
        }
 
_______________________________________________
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to