Bug 1954559 (CVE-2021-3520) - CVE-2021-3520 lz4: memory corruption due to an integer overflow bug caused by memmove argument
Summary: CVE-2021-3520 lz4: memory corruption due to an integer overflow bug caused by...
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2021-3520
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 1959427 1959430 1954560 1957036 1957037 1957038 1959428 1959429 1959431 1959432 1959433 1959434 1959435 1959437 1959438 1959439 1959440 1959441 1959442
Blocks: 1935389
TreeView+ depends on / blocked
 
Reported: 2021-04-28 11:36 UTC by Dhananjay Arunesh
Modified: 2023-09-15 12:31 UTC (History)
48 users (show)

Fixed In Version: lz4 1.9.4
Doc Type: If docs needed, set a value
Doc Text:
There's a flaw in lz4. An attacker who submits a crafted file to an application linked with lz4 may be able to trigger an integer overflow, leading to calling of memmove() on a negative size argument, causing an out-of-bounds write and/or a crash. The greatest impact of this flaw is to availability, with some potential impact to confidentiality and integrity as well.
Clone Of:
Environment:
Last Closed: 2021-06-29 16:41:14 UTC
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2021:2575 0 None None None 2021-06-29 16:31:00 UTC
Red Hat Product Errata RHSA-2022:1345 0 None None None 2022-04-13 11:27:06 UTC
Red Hat Product Errata RHSA-2022:5606 0 None None None 2022-07-19 13:40:24 UTC
Red Hat Product Errata RHSA-2022:6407 0 None None None 2022-09-09 07:12:38 UTC

Description Dhananjay Arunesh 2021-04-28 11:36:37 UTC
A vulnerability was found in lz4, where a potential memory corruption due to an integer overflow bug which caused one of the memmove arguments to become negative. Depending on how the library was compiled this will hit an assert() inside the library and dump core, leaving a 4GB core file, or it wil go into libc and crash inside the memmove() function.

Reference:
https://github.com/lz4/lz4/pull/972

Comment 1 Dhananjay Arunesh 2021-04-28 11:38:13 UTC
Created lz4 tracking bugs for this issue:

Affects: fedora-all [bug 1954560]

Comment 3 Todd Cullum 2021-05-04 21:48:33 UTC
The lz4 binary itself catches the problem when it parses the header, but it seems not all library consumers do and therefore LZ4_decompress_generic() was patched.

Comment 5 Todd Cullum 2021-05-04 22:06:09 UTC
Statement:

This flaw is out of support scope for Red Hat Enterprise Linux 7. To learn more about Red Hat Enterprise Linux support life cycles, please see https://access.redhat.com/support/policy/updates/errata .

Comment 6 Todd Cullum 2021-05-04 22:40:26 UTC
Flaw summary:

In the LZ4_decompress_generic() routine, outputSize is retrieved from the lz4 file and is an integer. A code path allows outputSize to influence the value of `length` via `oend` in the call to memmove(op, ip, length). A crafted file can cause outputSize to be a negative value, and since length is interpreted by memmove() as a size_t, it can be an extremely large, out-of-bounds value. The upstream patch checks to ensure that outputSize is not less than 0 at the beginning of the routine.

Comment 11 errata-xmlrpc 2021-06-29 16:30:56 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 8

Via RHSA-2021:2575 https://access.redhat.com/errata/RHSA-2021:2575

Comment 12 Product Security DevOps Team 2021-06-29 16:41:14 UTC
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s):

https://access.redhat.com/security/cve/cve-2021-3520

Comment 13 errata-xmlrpc 2022-04-13 11:27:02 UTC
This issue has been addressed in the following products:

  Red Hat AMQ Streams 2.1.0

Via RHSA-2022:1345 https://access.redhat.com/errata/RHSA-2022:1345

Comment 16 errata-xmlrpc 2022-07-19 13:40:22 UTC
This issue has been addressed in the following products:

  RHINT Camel-Q 2.7

Via RHSA-2022:5606 https://access.redhat.com/errata/RHSA-2022:5606

Comment 17 errata-xmlrpc 2022-09-09 07:12:34 UTC
This issue has been addressed in the following products:

  RHAF Camel-K 1.8

Via RHSA-2022:6407 https://access.redhat.com/errata/RHSA-2022:6407

Comment 18 Yann Collet 2022-10-19 08:12:45 UTC
There are a nb of incorrect statements in this thread, and I want to provide a counterpoint for anyone willing to take the time to understand this topic.

Probably the most incorrect statement is contained in this assertion : 
"A crafted file can cause outputSize to be a negative value"

Absolutely not.

The #972 patch is completely unrelated to the payload ingested by the `LZ4_decompress*()` function, meaning there is no attack possible through a "crafted file" vector.

What https://github.com/lz4/lz4/pull/972 covers is an _incorrect usage of the interface_ , by extending the contract of this interface.

The incorrect usage is providing an incorrect parameter as output buffer size, aka a wrong buffer size.
Providing a wrong buffer size is considered UB territory, same class as providing a wrong pointer.
That being said, in #972 the contract has been extended to detect and return a specific case when the size parameter is so completely wrong that it is negative.
Note that this contract extension does not cover situations where the size is incorrect (too large) but still positive.

And neither should it try to.
All interface contracts have limits, and providing obviously bogus parameters should not be classified as a CVE for the called function.
It might be a CVE, but then for the _caller_ of the function.

It follows that any implementation that correctly invokes the LZ4 decoder interface was never at risk.

Other fixable statements seen in this thread : 
- "a potential memory corruption due to an integer overflow" : it's not an integer overflow, it's a careless cast to `int` on the _user side_ of the code base (before invoking LZ4_decompress*() function)
- "In the LZ4_decompress_generic() routine, outputSize is retrieved from the lz4 file" : LZ4_decompress*() never "retrieves" any size, it has no <stdio.h> dependency, it's unaware of the concept of file. What it does is receive an `outputSize` parameter. This parameter is controlled by the caller.

Not mentioned in the thread, but probably worth mentioning : 
In the initial issue, the issuer illustrates the issue with this example : "If the decompressed size is big enough, e.g. 0xff000000-0xffffffff".
The reference lz4 implementation publishes a _maximum block size_ as part of its interface, and is documented as not supporting single blocks larger than this maximum.
This maximum size is set at 0x7E000000 (https://github.com/lz4/lz4/blob/dev/lib/lz4.h#L212).
Hence, the examples are way out of range of the library contract.

PS : I'm not aware of, or don't know about, any process to "declassify" a CVE, so these comments are mostly provided for context.

Comment 19 khalaniaspyn2 2022-11-25 07:01:44 UTC Comment hidden (spam)
Comment 20 sonnylee 2023-05-16 08:04:14 UTC Comment hidden (spam)
Comment 21 paulahong 2023-05-17 01:29:48 UTC Comment hidden (spam)
Comment 22 SaintOtis12 2023-06-27 06:35:27 UTC Comment hidden (spam)
Comment 23 larryellison 2023-08-07 07:01:04 UTC Comment hidden (spam)
Comment 24 orlandoolivia106@gmail.com 2023-09-15 12:31:05 UTC Comment hidden (spam)

Note You need to log in before you can comment on or make changes to this bug.