##// END OF EJS Templates
parsers: fix infinite loop or out-of-bound read in fm1readmarkers (issue4888)...
Yuya Nishihara -
r26591:04234431 default
parent child Browse files
Show More
@@ -2549,6 +2549,7 b' bail:'
2549
2549
2550 #define BUMPED_FIX 1
2550 #define BUMPED_FIX 1
2551 #define USING_SHA_256 2
2551 #define USING_SHA_256 2
2552 #define FM1_HEADER_SIZE (4 + 8 + 2 + 2 + 1 + 1 + 1)
2552
2553
2553 static PyObject *readshas(
2554 static PyObject *readshas(
2554 const char *source, unsigned char num, Py_ssize_t hashwidth)
2555 const char *source, unsigned char num, Py_ssize_t hashwidth)
@@ -2570,8 +2571,10 b' static PyObject *readshas('
2570 return list;
2571 return list;
2571 }
2572 }
2572
2573
2573 static PyObject *fm1readmarker(const char *data, uint32_t *msize)
2574 static PyObject *fm1readmarker(const char *databegin, const char *dataend,
2575 uint32_t *msize)
2574 {
2576 {
2577 const char *data = databegin;
2575 const char *meta;
2578 const char *meta;
2576
2579
2577 double mtime;
2580 double mtime;
@@ -2584,6 +2587,10 b' static PyObject *fm1readmarker(const cha'
2584 PyObject *metadata = NULL, *ret = NULL;
2587 PyObject *metadata = NULL, *ret = NULL;
2585 int i;
2588 int i;
2586
2589
2590 if (data + FM1_HEADER_SIZE > dataend) {
2591 goto overflow;
2592 }
2593
2587 *msize = getbe32(data);
2594 *msize = getbe32(data);
2588 data += 4;
2595 data += 4;
2589 mtime = getbefloat64(data);
2596 mtime = getbefloat64(data);
@@ -2601,12 +2608,23 b' static PyObject *fm1readmarker(const cha'
2601 nparents = (unsigned char)(*data++);
2608 nparents = (unsigned char)(*data++);
2602 nmetadata = (unsigned char)(*data++);
2609 nmetadata = (unsigned char)(*data++);
2603
2610
2611 if (databegin + *msize > dataend) {
2612 goto overflow;
2613 }
2614 dataend = databegin + *msize; /* narrow down to marker size */
2615
2616 if (data + hashwidth > dataend) {
2617 goto overflow;
2618 }
2604 prec = PyString_FromStringAndSize(data, hashwidth);
2619 prec = PyString_FromStringAndSize(data, hashwidth);
2605 data += hashwidth;
2620 data += hashwidth;
2606 if (prec == NULL) {
2621 if (prec == NULL) {
2607 goto bail;
2622 goto bail;
2608 }
2623 }
2609
2624
2625 if (data + nsuccs * hashwidth > dataend) {
2626 goto overflow;
2627 }
2610 succs = readshas(data, nsuccs, hashwidth);
2628 succs = readshas(data, nsuccs, hashwidth);
2611 if (succs == NULL) {
2629 if (succs == NULL) {
2612 goto bail;
2630 goto bail;
@@ -2614,6 +2632,9 b' static PyObject *fm1readmarker(const cha'
2614 data += nsuccs * hashwidth;
2632 data += nsuccs * hashwidth;
2615
2633
2616 if (nparents == 1 || nparents == 2) {
2634 if (nparents == 1 || nparents == 2) {
2635 if (data + nparents * hashwidth > dataend) {
2636 goto overflow;
2637 }
2617 parents = readshas(data, nparents, hashwidth);
2638 parents = readshas(data, nparents, hashwidth);
2618 if (parents == NULL) {
2639 if (parents == NULL) {
2619 goto bail;
2640 goto bail;
@@ -2623,6 +2644,9 b' static PyObject *fm1readmarker(const cha'
2623 parents = Py_None;
2644 parents = Py_None;
2624 }
2645 }
2625
2646
2647 if (data + 2 * nmetadata > dataend) {
2648 goto overflow;
2649 }
2626 meta = data + (2 * nmetadata);
2650 meta = data + (2 * nmetadata);
2627 metadata = PyTuple_New(nmetadata);
2651 metadata = PyTuple_New(nmetadata);
2628 if (metadata == NULL) {
2652 if (metadata == NULL) {
@@ -2632,6 +2656,9 b' static PyObject *fm1readmarker(const cha'
2632 PyObject *tmp, *left = NULL, *right = NULL;
2656 PyObject *tmp, *left = NULL, *right = NULL;
2633 Py_ssize_t leftsize = (unsigned char)(*data++);
2657 Py_ssize_t leftsize = (unsigned char)(*data++);
2634 Py_ssize_t rightsize = (unsigned char)(*data++);
2658 Py_ssize_t rightsize = (unsigned char)(*data++);
2659 if (meta + leftsize + rightsize > dataend) {
2660 goto overflow;
2661 }
2635 left = PyString_FromStringAndSize(meta, leftsize);
2662 left = PyString_FromStringAndSize(meta, leftsize);
2636 meta += leftsize;
2663 meta += leftsize;
2637 right = PyString_FromStringAndSize(meta, rightsize);
2664 right = PyString_FromStringAndSize(meta, rightsize);
@@ -2649,6 +2676,10 b' static PyObject *fm1readmarker(const cha'
2649 }
2676 }
2650 ret = Py_BuildValue("(OOHO(di)O)", prec, succs, flags,
2677 ret = Py_BuildValue("(OOHO(di)O)", prec, succs, flags,
2651 metadata, mtime, (int)tz * 60, parents);
2678 metadata, mtime, (int)tz * 60, parents);
2679 goto bail; /* return successfully */
2680
2681 overflow:
2682 PyErr_SetString(PyExc_ValueError, "overflow in obsstore");
2652 bail:
2683 bail:
2653 Py_XDECREF(prec);
2684 Py_XDECREF(prec);
2654 Py_XDECREF(succs);
2685 Py_XDECREF(succs);
@@ -2660,7 +2691,7 b' bail:'
2660
2691
2661
2692
2662 static PyObject *fm1readmarkers(PyObject *self, PyObject *args) {
2693 static PyObject *fm1readmarkers(PyObject *self, PyObject *args) {
2663 const char *data;
2694 const char *data, *dataend;
2664 Py_ssize_t datalen;
2695 Py_ssize_t datalen;
2665 Py_ssize_t offset, stop;
2696 Py_ssize_t offset, stop;
2666 PyObject *markers = NULL;
2697 PyObject *markers = NULL;
@@ -2668,6 +2699,7 b' static PyObject *fm1readmarkers(PyObject'
2668 if (!PyArg_ParseTuple(args, "s#nn", &data, &datalen, &offset, &stop)) {
2699 if (!PyArg_ParseTuple(args, "s#nn", &data, &datalen, &offset, &stop)) {
2669 return NULL;
2700 return NULL;
2670 }
2701 }
2702 dataend = data + datalen;
2671 data += offset;
2703 data += offset;
2672 markers = PyList_New(0);
2704 markers = PyList_New(0);
2673 if (!markers) {
2705 if (!markers) {
@@ -2676,7 +2708,7 b' static PyObject *fm1readmarkers(PyObject'
2676 while (offset < stop) {
2708 while (offset < stop) {
2677 uint32_t msize;
2709 uint32_t msize;
2678 int error;
2710 int error;
2679 PyObject *record = fm1readmarker(data, &msize);
2711 PyObject *record = fm1readmarker(data, dataend, &msize);
2680 if (!record) {
2712 if (!record) {
2681 goto bail;
2713 goto bail;
2682 }
2714 }
General Comments 0
You need to be logged in to leave comments. Login now