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