Mercurial > hg
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; |