comparison 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
comparison
equal deleted inserted replaced
40803:44c2e80db985 40812:9cdd525d97b2
155 } 155 }
156 156
157 return (const char *)(self->buf.buf) + pos * v1_hdrsize; 157 return (const char *)(self->buf.buf) + pos * v1_hdrsize;
158 } 158 }
159 159
160 /*
161 * Get parents of the given rev.
162 *
163 * The specified rev must be valid and must not be nullrev. A returned
164 * parent revision may be nullrev, but is guaranteed to be in valid range.
165 */
160 static inline int index_get_parents(indexObject *self, Py_ssize_t rev, 166 static inline int index_get_parents(indexObject *self, Py_ssize_t rev,
161 int *ps, int maxrev) 167 int *ps, int maxrev)
162 { 168 {
163 if (rev >= self->length) { 169 if (rev >= self->length) {
164 PyObject *tuple = PyList_GET_ITEM(self->added, rev - self->length); 170 PyObject *tuple = PyList_GET_ITEM(self->added, rev - self->length);
169 ps[0] = getbe32(data + 24); 175 ps[0] = getbe32(data + 24);
170 ps[1] = getbe32(data + 28); 176 ps[1] = getbe32(data + 28);
171 } 177 }
172 /* If index file is corrupted, ps[] may point to invalid revisions. So 178 /* If index file is corrupted, ps[] may point to invalid revisions. So
173 * there is a risk of buffer overflow to trust them unconditionally. */ 179 * there is a risk of buffer overflow to trust them unconditionally. */
174 if (ps[0] > maxrev || ps[1] > maxrev) { 180 if (ps[0] < -1 || ps[0] > maxrev || ps[1] < -1 || ps[1] > maxrev) {
175 PyErr_SetString(PyExc_ValueError, "parent out of range"); 181 PyErr_SetString(PyExc_ValueError, "parent out of range");
176 return -1; 182 return -1;
177 } 183 }
178 return 0; 184 return 0;
179 } 185 }