Summary
Memory corruption can be achieved by parsing a RAW picture containing malicious Leaf metadata.
Severity
High - The values written out of bounds are read directly from the input and the size of the overflow is controllable by the length of the input file. If the target binary is compiled with the “-DLIBRAW_NOTHREADS” flag, the overflow manifests in stack memory; without such a flag it manifests in heap memory.
Proof of Concept
- Compile LibRaw following the instructions on https://github.com/LibRaw/LibRaw/blob/0.21.2/INSTALL
- Run the
bin/simple_dcraw
sample binary with the provided file: bin/simple_dcraw poc.bin
Further Analysis
LibRaw allows the input file to contain metadata commonly used by different vendors, so it is possible to induce it into recognizing an input file as a Panasonic RAW picture by including a combination of TIFF tags.
Among the supported TIFF tags, LibRaw supports metadata in the Leaf format. Such metadata is identified by a 0x8606 TIFF tag and it is handled by the LibRaw::parse_mos
function. Along with other fields, it is possible to control the load_flags
variable via a Rows_data
entry: https://github.com/LibRaw/LibRaw/blob/0.21.2/src/metadata/mediumformat.cpp#L514
load_flags
is an interesting variable: it is used in LibRaw::pana_data
to limit how many bytes are copied - at most - from the input file, and at which offset into a target buffer, in case it is recognized by LibRaw as a Panasonic RAW picture: https://github.com/LibRaw/LibRaw/blob/0.21.2/src/decoders/decoders_dcraw.cpp#L1102
By specifying load_flags
greater than 0x4000 it is possible to make the result of the subtraction wraparound and write outside of the destination buffer bounds: LibRaw::fread
will try to read up to a huge amount of bytes into a buffer buf
of size 0x4002. Such a buffer is allocated on the stack if the target binary is compiled with the “-DLIBRAW_NOTHREADS” flag, otherwise in the heap.
Timeline
Date reported: 09/13/2024
Date fixed: 09/18/2024
Date disclosed: 10/18/2024
Summary
Memory corruption can be achieved by parsing a RAW picture containing malicious Leaf metadata.
Severity
High - The values written out of bounds are read directly from the input and the size of the overflow is controllable by the length of the input file. If the target binary is compiled with the “-DLIBRAW_NOTHREADS” flag, the overflow manifests in stack memory; without such a flag it manifests in heap memory.
Proof of Concept
bin/simple_dcraw
sample binary with the provided file: bin/simple_dcraw poc.binFurther Analysis
LibRaw allows the input file to contain metadata commonly used by different vendors, so it is possible to induce it into recognizing an input file as a Panasonic RAW picture by including a combination of TIFF tags.
Among the supported TIFF tags, LibRaw supports metadata in the Leaf format. Such metadata is identified by a 0x8606 TIFF tag and it is handled by the
LibRaw::parse_mos
function. Along with other fields, it is possible to control theload_flags
variable via aRows_data
entry: https://github.com/LibRaw/LibRaw/blob/0.21.2/src/metadata/mediumformat.cpp#L514load_flags
is an interesting variable: it is used inLibRaw::pana_data
to limit how many bytes are copied - at most - from the input file, and at which offset into a target buffer, in case it is recognized by LibRaw as a Panasonic RAW picture: https://github.com/LibRaw/LibRaw/blob/0.21.2/src/decoders/decoders_dcraw.cpp#L1102By specifying
load_flags
greater than 0x4000 it is possible to make the result of the subtraction wraparound and write outside of the destination buffer bounds:LibRaw::fread
will try to read up to a huge amount of bytes into a bufferbuf
of size 0x4002. Such a buffer is allocated on the stack if the target binary is compiled with the “-DLIBRAW_NOTHREADS” flag, otherwise in the heap.Timeline
Date reported: 09/13/2024
Date fixed: 09/18/2024
Date disclosed: 10/18/2024