Problem:
cupsSideChannelSNMPGet() takes the OID length from strlen(real_data) + 1 without checking that the nul terminator is inside the real_datalen bytes the backend actually sent, so strlen() runs into the uninitialised tail of the _cupsBufferGet() buffer. real_datalen then goes negative, the "(real_datalen + 1) > *datalen" check passes for any caller buffer, and memcpy() gets (size_t)real_datalen as its size.
|
real_oidlen = (int)strlen(real_data) + 1; |
|
real_datalen -= real_oidlen; |
|
|
|
if ((real_datalen + 1) > *datalen) |
|
{ |
|
_cupsBufferRelease(real_data); |
|
return (CUPS_SC_STATUS_TOO_BIG); |
|
} |
|
|
|
memcpy(data, real_data + real_oidlen, (size_t)real_datalen); |
cupsSideChannelSNMPWalk() has the same flaw and its guard against it, "if ((size_t)real_datalen < sizeof(real_data))", measures a char pointer instead of the 65540 byte buffer, so it only fires when real_datalen is below 8.
Found by Linux Verification Center (portal.linuxtesting.ru) with SVACE.
Reporter: Pavel Nekrasov (p.nekrasov@fobos-nt.ru).
Problem:
cupsSideChannelSNMPGet() takes the OID length from strlen(real_data) + 1 without checking that the nul terminator is inside the real_datalen bytes the backend actually sent, so strlen() runs into the uninitialised tail of the _cupsBufferGet() buffer. real_datalen then goes negative, the "(real_datalen + 1) > *datalen" check passes for any caller buffer, and memcpy() gets (size_t)real_datalen as its size.
cups/cups/sidechannel.c
Lines 322 to 331 in e72b702
cupsSideChannelSNMPWalk() has the same flaw and its guard against it, "if ((size_t)real_datalen < sizeof(real_data))", measures a char pointer instead of the 65540 byte buffer, so it only fires when real_datalen is below 8.
Found by Linux Verification Center (portal.linuxtesting.ru) with SVACE.
Reporter: Pavel Nekrasov (p.nekrasov@fobos-nt.ru).