$NetBSD: patch-au,v 1.9 2007/11/05 20:16:19 adrianp Exp $ # CVE-2007-4351 --- cups/ipp.c.orig 2007-02-05 20:25:50.000000000 +0000 +++ cups/ipp.c @@ -1315,6 +1315,12 @@ ippReadIO(void *src, /* I - Data { case IPP_TAG_INTEGER : case IPP_TAG_ENUM : + if (n != 4) + { + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); + } + if ((*cb)(src, buffer, 4) < 4) { DEBUG_puts("ippReadIO: Unable to read integer value!"); @@ -1327,6 +1333,12 @@ ippReadIO(void *src, /* I - Data value->integer = n; break; case IPP_TAG_BOOLEAN : + if (n != 1) + { + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); + } + if ((*cb)(src, buffer, 1) < 1) { DEBUG_puts("ippReadIO: Unable to read boolean value!"); @@ -1344,6 +1356,12 @@ ippReadIO(void *src, /* I - Data case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : + if (n >= sizeof(buffer)) + { + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); + } + if ((*cb)(src, buffer, n) < n) { DEBUG_puts("ippReadIO: unable to read name!"); @@ -1356,6 +1374,12 @@ ippReadIO(void *src, /* I - Data value->string.text)); break; case IPP_TAG_DATE : + if (n != 11) + { + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); + } + if ((*cb)(src, value->date, 11) < 11) { DEBUG_puts("ippReadIO: Unable to date integer value!"); @@ -1363,6 +1387,12 @@ ippReadIO(void *src, /* I - Data } break; case IPP_TAG_RESOLUTION : + if (n != 9) + { + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); + } + if ((*cb)(src, buffer, 9) < 9) { DEBUG_puts("ippReadIO: Unable to read resolution value!"); @@ -1379,6 +1409,12 @@ ippReadIO(void *src, /* I - Data (ipp_res_t)buffer[8]; break; case IPP_TAG_RANGE : + if (n != 8) + { + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); + } + if ((*cb)(src, buffer, 8) < 8) { DEBUG_puts("ippReadIO: Unable to read range value!"); @@ -1394,7 +1430,7 @@ ippReadIO(void *src, /* I - Data break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : - if (n > sizeof(buffer) || n < 4) + if (n >= sizeof(buffer) || n < 4) { DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); return (IPP_ERROR); @@ -1420,22 +1456,27 @@ ippReadIO(void *src, /* I - Data n = (bufptr[0] << 8) | bufptr[1]; - if (n >= sizeof(string)) + if ((bufptr + 2 + n) >= (buffer + sizeof(buffer)) || + n >= sizeof(string)) { - memcpy(string, bufptr + 2, sizeof(string) - 1); - string[sizeof(string) - 1] = '\0'; + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); } - else - { - memcpy(string, bufptr + 2, n); - string[n] = '\0'; - } + + memcpy(string, bufptr + 2, n); + string[n] = '\0'; value->string.charset = _cupsStrAlloc((char *)string); bufptr += 2 + n; n = (bufptr[0] << 8) | bufptr[1]; + if ((bufptr + 2 + n) >= (buffer + sizeof(buffer))) + { + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); + } + bufptr[2 + n] = '\0'; value->string.text = _cupsStrAlloc((char *)bufptr + 2); break; @@ -1477,6 +1518,12 @@ ippReadIO(void *src, /* I - Data * we need to carry over... */ + if (n >= sizeof(buffer)) + { + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); + } + if ((*cb)(src, buffer, n) < n) { DEBUG_puts("ippReadIO: Unable to read member name value!"); @@ -1498,6 +1545,12 @@ ippReadIO(void *src, /* I - Data break; default : /* Other unsupported values */ + if (n > sizeof(buffer)) + { + DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); + return (IPP_ERROR); + } + value->unknown.length = n; if (n > 0) {