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