comparison mercurial/cext/revlog.c @ 40813:884321cd26c3 stable

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. This is NOT a security fix as there's no Python code triggering the bug, but included in this series to not give a notion about the memory issue fixed by the previous patch.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 28 Oct 2018 21:29:04 +0900
parents 9cdd525d97b2
children cb372d09d30a f4113489e4d4
comparison
equal deleted inserted replaced
40812:9cdd525d97b2 40813:884321cd26c3
2312 }; 2312 };
2313 2313
2314 /* FFI exposed from Rust code */ 2314 /* FFI exposed from Rust code */
2315 rustlazyancestorsObject *rustlazyancestors_init( 2315 rustlazyancestorsObject *rustlazyancestors_init(
2316 indexObject *index, 2316 indexObject *index,
2317 /* to pass index_get_parents() */ 2317 /* to pass index_get_parents_checked() */
2318 int (*)(indexObject *, Py_ssize_t, int*, int), 2318 int (*)(indexObject *, Py_ssize_t, int*, int),
2319 /* intrevs vector */ 2319 /* intrevs vector */
2320 Py_ssize_t initrevslen, long *initrevs, 2320 Py_ssize_t initrevslen, long *initrevs,
2321 long stoprev, 2321 long stoprev,
2322 int inclusive); 2322 int inclusive);
2323 void rustlazyancestors_drop(rustlazyancestorsObject *self); 2323 void rustlazyancestors_drop(rustlazyancestorsObject *self);
2324 int rustlazyancestors_next(rustlazyancestorsObject *self); 2324 int rustlazyancestors_next(rustlazyancestorsObject *self);
2325 int rustlazyancestors_contains(rustlazyancestorsObject *self, long rev); 2325 int rustlazyancestors_contains(rustlazyancestorsObject *self, long rev);
2326
2327 static int index_get_parents_checked(indexObject *self, Py_ssize_t rev,
2328 int *ps, int maxrev)
2329 {
2330 if (rev < 0 || rev >= index_length(self)) {
2331 PyErr_SetString(PyExc_ValueError, "rev out of range");
2332 return -1;
2333 }
2334 return index_get_parents(self, rev, ps, maxrev);
2335 }
2326 2336
2327 /* CPython instance methods */ 2337 /* CPython instance methods */
2328 static int rustla_init(rustlazyancestorsObject *self, 2338 static int rustla_init(rustlazyancestorsObject *self,
2329 PyObject *args) { 2339 PyObject *args) {
2330 PyObject *initrevsarg = NULL; 2340 PyObject *initrevsarg = NULL;
2362 } 2372 }
2363 if (PyErr_Occurred()) 2373 if (PyErr_Occurred())
2364 goto bail; 2374 goto bail;
2365 2375
2366 self->iter = rustlazyancestors_init(index, 2376 self->iter = rustlazyancestors_init(index,
2367 index_get_parents, 2377 index_get_parents_checked,
2368 linit, initrevs, 2378 linit, initrevs,
2369 stoprev, inclusive); 2379 stoprev, inclusive);
2370 if (self->iter == NULL) { 2380 if (self->iter == NULL) {
2371 /* if this is because of GraphError::ParentOutOfRange 2381 /* if this is because of GraphError::ParentOutOfRange
2372 * index_get_parents() has already set the proper ValueError */ 2382 * index_get_parents_checked() has already set the proper
2383 * ValueError */
2373 goto bail; 2384 goto bail;
2374 } 2385 }
2375 2386
2376 free(initrevs); 2387 free(initrevs);
2377 return 0; 2388 return 0;