|
Message-ID: <CAFkuX4uK6p8qzCgrJSUMY+6UaKw0dQN1PSC0zLrFD6N3ki7F9A@mail.gmail.com> Date: Thu, 26 Jun 2014 12:55:58 -0600 From: "Don A. Bailey" <donb@...uritymouse.com> To: oss-security@...ts.openwall.com Subject: LMS-2014-06-16-4: FFmpeg LZO Hello All, A vulnerability has been identified in the FFmpeg LZO implementation. Please find the bug report attached inline. Best, Don A. Bailey Founder / CEO Lab Mouse Security https://www.securitymouse.com/ ############################################################################# # # Lab Mouse Security Report # LMS-2014-06-16-4 # Report ID: LMS-2014-06-16-4 CVE ID: CVE-2014-4610 Researcher Name: Don A. Bailey Researcher Organization: Lab Mouse Security Researcher Email: donb at securitymouse.com Researcher Website: www.securitymouse.com Vulnerability Status: Patched Vulnerability Embargo: Broken Vulnerability Class: Integer Overflow Vulnerability Effect: Memory Corruption Vulnerability Impact: DoS, OOW, RCE Vulnerability DoS Practicality: Practical Vulnerability OOW Practicality: Practical Vulnerability RCE Practicality: Practical Vulnerability Criticality: Critical Vulnerability Scope: All versions of libav are affected. All architectures supported by libav are affected. Vulnerability Tested: Yes. RCE proven on 10 separate platforms including but not limited to: - Ubuntu and Mint x86, x86_64 - Debian x86_64, x86 - FreeBSD x86_64, x86 Functions Affected: libavutil/lzo.c:av_lzo1x_decode Criticality Reasoning --------------------- This vulnerability can be triggered through a compression payload embedded in a video file. Due to the nature of this memory corruption vulnerability, exploitation of the bug can be seamless and work in the background during normal video playback. A user will never notice that playback has been compromised. Vulnerability Description ------------------------- An integer overflow can occur when processing any variant of a "literal run" in the av_lzo1x_decode function. Each of these three locations is subject to an integer overflow when processing zero bytes. The following code depicts how the size of the literal array is generated: static inline int get_len(LZOContext *c, int x, int mask) { int cnt = x & mask; if (!cnt) { while (!(x = get_byte(c))) cnt += 255; cnt += mask + x; } return cnt; } As long as a zero byte (0x00) is encountered, the variable 'cnt' will be incremented by 255. Using approximately sixteen megabytes of zeros, 'cnt' will accumulate to a maximum unsigned integer value in the 32bit variable. Therefore, get_len() will return a negative 'cnt' value to its caller. The checks in copy_backptr() will fail to properly test for negative 'cnt' values resulting in the following test never catching an error: if (cnt > c->out_end - dst) { cnt = FFMAX(c->out_end - dst, 0); c->error |= AV_LZO_OUTPUT_FULL; } av_memcpy_backptr does not check for negative 'cnt' values, which results in a copy of one byte from 'src' to 'dst', evading a crash do to excessive copying. Finally, the copy function will never crash by calling memcpy with a negative value because it only calls memcpy when the signed 'cnt' variable is greater than zero. However, the pointers 'c->in' and 'c->out' will still be adjusted by a negative value, causing 'c->out' to point to an area of memory prior to the actual output buffer. It is notable that since the count value 'cnt' is passed around as an 'int', it will always be interpreted as a signed 32bit integer regardless of the underlying architecture. This means that this vulnerability affects all platforms and architectures regardless of whether they are 32bit or 64bit in nature. Vulnerability Resolution ------------------------ Resolving this issue requires several separate fixes. 1) lzo.c:get_len() The return value of get_len must be evaluated for negative count values. A negative value should never be allowed in this context. Always error when a negative or zero value is returned. 2) lzo.c:copy() A negative value should not be allowed as a parameter to copy(). In addition, the pointers 'c->in' and 'c->out' should be tested after they are changed by the count value. Verify that the new offset does not land outside of the bounds of the 'out' buffer. 3) lzo:copy_backptr() Do not allow a negative 'cnt' value to be passed to copy_backptr. Augment the test cases to ensure that a negative value cannot be used to adjust the 'c->out' pointer. 4) libavutil/mem.c:av_memcpy_backptr Return an error value. Do not allow a negative 'cnt' or 'back' value to be used. 5) Always use a size_t for any size variable. Size variables should always represent the underlying architecture's largest natural unsigned integer. Use size_t, or a variant, to automatically scale the value to the underlying architecture.
Powered by blists - more mailing lists
Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.