Skip to content

Segmentation Fault in BmpInput::read_native_scanline (bmpinput.cpp:399)

Moderate
lgritz published GHSA-q3c7-3225-66h7 Jun 4, 2026

Package

No package listed

Affected versions

< 3.0.16.0, < 3.1.11.0

Patched versions

>= 3.0.16.0, >= 3.1.11.0, >= 3.2.0.0

Description

Summary

We discovered a Segmentation Fault (SEGV) in OpenImageIO's BMP image handling.
The crash occurs in OpenImageIO::v3_2_0::BmpInput::read_native_scanline at src/bmp.imageio/bmpinput.cpp:399:38 when processing a crafted BMP file via oiiotool. The crash has been fixed in PR 5030.

Details

  • OS: Linux x86_64
  • Affected Version: commit e1575d2 and before
  • Vulnerability Type: Segmentation Fault (Invalid Read)
  • Location: src/bmp.imageio/bmpinput.cpp:399:38

PoC

  1. Compile OpenImageIO with Clang and AddressSanitizer enabled.
  2. Run oiiotool with the PoC file:
./build-afl/bin/oiiotool repro.bmp -o /tmp/dummy.bmp
ASAN report
AddressSanitizer:DEADLYSIGNAL
=================================================================
==92402==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x7fdd8df70037 bp 0xffffffffffffffff sp 0x7fff7065e920 T0)
==92402==The signal is caused by a READ memory access.
==92402==Hint: this fault was caused by a dereference of a high value address (see register values below).  Disassemble the provided pc to learn which register was used.
    #0 0x7fdd8df70037 in OpenImageIO::v3_2_0::BmpInput::read_native_scanline(int, int, int, int, void*) /src/OpenImageIO/src/bmp.imageio/bmpinput.cpp:399:38
    #1 0x7fdd8dc410a6 in OpenImageIO::v3_1::ImageInput::read_native_scanlines(int, int, int, int, int, void*) /src/OpenImageIO/src/libOpenImageIO/imageinput.cpp:491:19
    #2 0x7fdd8dc41746 in OpenImageIO::v3_1::ImageInput::read_native_scanlines(int, int, int, int, int, int, int, void*) /src/OpenImageIO/src/libOpenImageIO/imageinput.cpp:512:16
    #3 0x7fdd8dc43a7c in OpenImageIO::v3_1::ImageInput::read_native_scanlines(int, int, int, int, int, int, OpenImageIO::v3_1::span<std::byte, 18446744073709551615ul>) /src/OpenImageIO/src/libOpenImageIO/imageinput.cpp:590:12
    #4 0x7fdd8dc3f29f in OpenImageIO::v3_1::ImageInput::read_scanlines(int, int, int, int, int, int, int, OpenImageIO::v3_1::TypeDesc, void*, long, long) /src/OpenImageIO/src/libOpenImageIO/imageinput.cpp:428:15
    #5 0x7fdd8dc4ff3d in OpenImageIO::v3_1::ImageInput::read_image(int, int, int, int, OpenImageIO::v3_1::TypeDesc, void*, long, long, long, bool (*)(void*, float), void*) /src/OpenImageIO/src/libOpenImageIO/imageinput.cpp:1168:23
    #6 0x7fdd8da4c27f in OpenImageIO::v3_1::ImageBufImpl::read(int, int, int, int, bool, OpenImageIO::v3_1::TypeDesc, bool (*)(void*, float), void*, OpenImageIO::v3_2_0::DoLock) /src/OpenImageIO/src/libOpenImageIO/imagebuf.cpp:1457:27
    #7 0x7fdd8da5bbbc in OpenImageIO::v3_1::ImageBuf::read(int, int, int, int, bool, OpenImageIO::v3_1::TypeDesc, bool (*)(void*, float), void*) /src/OpenImageIO/src/libOpenImageIO/imagebuf.cpp:1532:20
    #8 0x5625c6d36e0a in OpenImageIO::v3_2_0::OiioTool::ImageRec::read(OpenImageIO::v3_2_0::OiioTool::ReadPolicy, OpenImageIO::v3_1::basic_string_view<char, std::char_traits<char>>) /src/OpenImageIO/src/oiiotool/imagerec.cpp:356:27
    #9 0x5625c6d5b19d in OpenImageIO::v3_2_0::OiioTool::Oiiotool::read(std::shared_ptr<OpenImageIO::v3_2_0::OiioTool::ImageRec>, OpenImageIO::v3_2_0::OiioTool::ReadPolicy, OpenImageIO::v3_1::basic_string_view<char, std::char_traits<char>>) /src/OpenImageIO/src/oiiotool/oiiotool.cpp:413:20
    #10 0x5625c6d72e77 in OpenImageIO::v3_2_0::OiioTool::Oiiotool::read(OpenImageIO::v3_2_0::OiioTool::ReadPolicy, OpenImageIO::v3_1::basic_string_view<char, std::char_traits<char>>) /src/OpenImageIO/src/oiiotool/oiiotool.h:211:20
    #11 0x5625c6e9314a in output_file(OpenImageIO::v3_2_0::OiioTool::Oiiotool&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>) /src/OpenImageIO/src/oiiotool/oiiotool.cpp:5676:13
    #12 0x5625c6db852e in std::function<void (OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>::operator()(OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>) const /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_function.h:591:9
    #13 0x5625c6db852e in OpenImageIO::v3_1::ArgParse::Arg::action(std::function<void (OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>&&)::'lambda'(OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)::operator()(OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>) const /src/OpenImageIO/src/include/OpenImageIO/argparse.h:540:61
    #14 0x5625c6db852e in void std::__invoke_impl<void, OpenImageIO::v3_1::ArgParse::Arg::action(std::function<void (OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>&&)::'lambda'(OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)&, OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>>(std::__invoke_other, OpenImageIO::v3_1::ArgParse::Arg::action(std::function<void (OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>&&)::'lambda'(OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)&, OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>&&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61:14
    #15 0x5625c6db852e in std::enable_if<is_invocable_r_v<void, OpenImageIO::v3_1::ArgParse::Arg::action(std::function<void (OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>&&)::'lambda'(OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)&, OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>>, void>::type std::__invoke_r<void, OpenImageIO::v3_1::ArgParse::Arg::action(std::function<void (OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>&&)::'lambda'(OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)&, OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>>(OpenImageIO::v3_1::ArgParse::Arg::action(std::function<void (OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>&&)::'lambda'(OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)&, OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>&&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:111:2
    #16 0x5625c6db852e in std::_Function_handler<void (OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>), OpenImageIO::v3_1::ArgParse::Arg::action(std::function<void (OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>&&)::'lambda'(OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>::_M_invoke(std::_Any_data const&, OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>&&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_function.h:290:9
    #17 0x7fdd8be807dc in std::function<void (OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>)>::operator()(OpenImageIO::v3_1::ArgParse::Arg&, OpenImageIO::v3_1::span<char const* const, 18446744073709551615ul>) const /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_function.h:591:9
    #18 0x7fdd8be807dc in OpenImageIO::v3_1::ArgParse::Impl::parse_args(int, char const**) /src/OpenImageIO/src/libutil/argparse.cpp:537:25
    #19 0x7fdd8be7d6db in OpenImageIO::v3_1::ArgParse::parse_args(int, char const**) /src/OpenImageIO/src/libutil/argparse.cpp:431:21
    #20 0x5625c6d910b5 in OpenImageIO::v3_2_0::OiioTool::Oiiotool::getargs(int, char**) /src/OpenImageIO/src/oiiotool/oiiotool.cpp:7241:12
    #21 0x5625c6daa142 in main /src/OpenImageIO/src/oiiotool/oiiotool.cpp:7636:12
    #22 0x7fdd8b8431c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #23 0x7fdd8b84328a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #24 0x5625c6ba3f54 in _start (/src/OpenImageIO/build-afl/bin/oiiotool+0x70f54) (BuildId: a2245a89e4114b6fd88817a40f77bae3921e03f1)

==92402==Register values:
rax = 0x0000515000007ca0  rbx = 0x1fffffffffffffff  rcx = 0x00000a2a00000f8e  rdx = 0x00000a2a00000f8f  
rdi = 0x00007fdd72bf8800  rsi = 0xfffffffffffffffe  rbp = 0xffffffffffffffff  rsp = 0x00007fff7065e920  
 r8 = 0x0000000000000000   r9 = 0x00000a2a00000f62  r10 = 0x00007fdd72bf8802  r11 = 0x0000000000000000  
r12 = 0x0000515000007c78  r13 = 0x00000a2a00000f94  r14 = 0x0000515000007c70  r15 = 0x00000a2a00000f63  
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /src/OpenImageIO/src/bmp.imageio/bmpinput.cpp:399:38 in OpenImageIO::v3_2_0::BmpInput::read_native_scanline(int, int, int, int, void*)

==92402==ABORTING

Impact

A crafted BMP file can trigger an invalid memory read in OpenImageIO’s BMP decoder, causing the process to crash. This is a denial-of-service vulnerability affecting users or applications that process untrusted BMP files with OpenImageIO, including oiiotool and software linked against the OpenImageIO library.

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Local
Attack complexity
Low
Privileges required
None
User interaction
Required
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H

CVE ID

CVE-2026-50291

Weaknesses

Out-of-bounds Read

The product reads data past the end, or before the beginning, of the intended buffer. Learn more on MITRE.

Credits