Skip to content

[Bug] Runtime Error in types.cpp:582 #3519

@ShangzhiXu

Description

@ShangzhiXu

Describe the bug

Hi team~ Thanks for your work in exiv2, I think here's a small bug in types.cpp when handling large numbers in .xmp files.

Root cause

If there's a number Xmp.exif.Flash/exif:Mode =18446744073709551616 in a malicious .xmp file, code in types.cpp will handle it like this at line 580

  auto f = stringTo<float>(s, ok);
  if (ok)
    return static_cast<int64_t>(f); // crash here

f becomes approximately 1.84467e+19 and it is directly casted to int64_t.
Since this value exceeds INT64_MAX (9,223,372,036,854,775,807), the conversion overflows the representable range and triggers undefined behavior.

To Reproduce

Steps to reproduce the behavior:

PoC

poc.xmp

<?xml version="1.0" encoding="UTF-8"?>
<?xpacket begin="" id="AAAAAAAAA"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/">
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description rdf:about=""
      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:exif="http://ns.adobe.com/exif/1.0/"
      xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
      xmlns:aux="&amp;"
      xmlns:dc="http://purl.org/dc/elements/1.1/"
      xmlns:xmp="http://ns.adobe.com/xap/1.0/"
      xmlns:stVer="http://ns.adobe.com/xap/1.0/sType/Version#"
      xmp:CreateDate="2024-01-01T00:00:00ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
      xmp:MetadataDate="0000-00-00T00:00:00"
      exif:SceneCaptureType="1073741823"
      exif:StandardOutputSensitivity="2147483648"
      exif:FocalPlaneXResolution="99999999999999/1"
      exif:GPSLongitudeRef="/dev/urandom"
      aux:OwnerName="0o7777777777777777777777">
      <xmp:ModifyDate>--01-01</xmp:ModifyDate>
      <xmp:Label>XniMYrq/YO8fVX4q6WocH1BeiJu+DvT9DshmaiqBOmadabcwEmndzELuekgPQslq</xmp:Label>
      <xmp:Nickname>9223372036854775807LL</xmp:Nickname>
      <xmp:Identifier>16777215</xmp:Identifier>
      <exif:PixelXDimension>127</exif:PixelXDimension>
      <exif:PixelYDimension>255</exif:PixelYDimension>
      <exif:ExifVersion>0xFF</exif:ExifVersion>
      <exif:ComponentsConfiguration>+0x8000000000000000</exif:ComponentsConfiguration>
      <exif:MeteringMode>128</exif:MeteringMode>
      <exif:SensingMethod>9223372036854775807</exif:SensingMethod>
      <exif:WhiteBalance>255</exif:WhiteBalance>
      <exif:ImageUniqueID>-99999999999999999999999999999999999999999999999999</exif:ImageUniqueID>
      <exif:ISOSpeedLatitudezzz>16777215</exif:ISOSpeedLatitudezzz>
      <exif:ShutterSpeedValue>99999999999999/1</exif:ShutterSpeedValue>
      <exif:FocalLength>1/0 2/0 3/0</exif:FocalLength>
      <exif:FlashEnergy>-1/0</exif:FlashEnergy>
      <exif:DigitalZoomRatio>1/0 2/0 3/0</exif:DigitalZoomRatio>
      <exif:GPSLatitude></exif:GPSLatitude>
      <exif:GPSAltitude>0/0,0/0,0/0</exif:GPSAltitude>
      <exif:GPSSpeed>999,999,999N</exif:GPSSpeed>
      <exif:GPSDestDistanceRef>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ</exif:GPSDestDistanceRef>
      <exif:GPSDateStamp>2147483648</exif:GPSDateStamp>
      <exif:Flash>
          <rdf:Description>
            <exif:Fired>1</exif:Fired>
            <exif:Return>128</exif:Return>
            <exif:Mode>18446744073709551616</exif:Mode>
            <exif:Function>no</exif:Function>
            <exif:RedEyeMode>True</exif:RedEyeMode>
          </rdf:Description>
        </exif:Flash>
    </rdf:Description>
  </rdf:RDF>
</x:xmpmeta>
<?xpacket end="r"?>

We can trigger the crash with the command
z5500277@katana2:.../bin/crashes_xmp $ UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1:abort_on_error=1 ../exiv2 -pa poc.xmp
and we can see

z5500277@katana2:.../bin/crashes_xmp $ UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1:abort_on_error=1 ../exiv2 -pa poc.xmp
Warning: Failed to convert Xmp.xmp.ModifyDate to Exif.Image.DateTime (Invalid year in date string)
Warning: Failed to convert Xmp.xmp.CreateDate to Exif.Photo.DateTimeDigitized (Invalid date string, extra chars at end)
/srv/scratch/z5500277/target/exiv2/src/types.cpp:582:33: runtime error: 1.84467e+19 is outside the range of representable values of type 'long'
    #0 0x7f6030e72e0d in Exiv2::parseInt64(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool&) /srv/scratch/z5500277/target/exiv2/src/types.cpp:582:33
    #1 0x7f6030d100ca in Exiv2::Converter::cnvXmpFlash(char const*, char const*) /srv/scratch/z5500277/target/exiv2/src/convert.cpp:1063:22
    #2 0x7f6030d1b731 in void std::__invoke_impl<void, void (Exiv2::Converter::* const&)(char const*, char const*), Exiv2::Converter&, char const* const&, char const* const&>(std::__invoke_memfun_ref, void (Exiv2::Converter::* const&)(char const*, char const*), Exiv2::Converter&, char const* const&, char const* const&) /apps/z_install_tree/linux-rocky8-ivybridge/gcc-8.5.0/gcc-12.2.0-64v2gp5krz26bgfwfu32vmbm4ih2vodr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/invoke.h:67:14
    #3 0x7f6030d1b731 in std::__invoke_result<void (Exiv2::Converter::* const&)(char const*, char const*), Exiv2::Converter&, char const* const&, char const* const&>::type std::__invoke<void (Exiv2::Converter::* const&)(char const*, char const*), Exiv2::Converter&, char const* const&, char const* const&>(void (Exiv2::Converter::* const&)(char const*, char const*), Exiv2::Converter&, char const* const&, char const* const&) /apps/z_install_tree/linux-rocky8-ivybridge/gcc-8.5.0/gcc-12.2.0-64v2gp5krz26bgfwfu32vmbm4ih2vodr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/invoke.h:96:14
    #4 0x7f6030d1b731 in std::invoke_result<void (Exiv2::Converter::* const&)(char const*, char const*), Exiv2::Converter&, char const* const&, char const* const&>::type std::invoke<void (Exiv2::Converter::* const&)(char const*, char const*), Exiv2::Converter&, char const* const&, char const* const&>(void (Exiv2::Converter::* const&)(char const*, char const*), Exiv2::Converter&, char const* const&, char const* const&) /apps/z_install_tree/linux-rocky8-ivybridge/gcc-8.5.0/gcc-12.2.0-64v2gp5krz26bgfwfu32vmbm4ih2vodr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/functional:110:14
    #5 0x7f6030d1b731 in Exiv2::Converter::cnvFromXmp() /srv/scratch/z5500277/target/exiv2/src/convert.cpp:513:7
    #6 0x7f6030d2199f in Exiv2::copyXmpToExif(Exiv2::XmpData const&, Exiv2::ExifData&) /srv/scratch/z5500277/target/exiv2/src/convert.cpp:1332:13
    #7 0x7f6030f0b0ea in Exiv2::XmpSidecar::readMetadata() /srv/scratch/z5500277/target/exiv2/src/xmpsidecar.cpp:85:3
    #8 0x55f70747c65f in Action::Print::printList() /srv/scratch/z5500277/target/exiv2/app/actions.cpp:352:10
    #9 0x55f707476be2 in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /srv/scratch/z5500277/target/exiv2/app/actions.cpp
    #10 0x55f7074093e5 in main /srv/scratch/z5500277/target/exiv2/app/exiv2.cpp:182:25
    #11 0x7f602f14c864 in __libc_start_main (/lib64/libc.so.6+0x3a864) (BuildId: 1faac7cdefc71ce73027e33a84650684eecd1635)
    #12 0x55f70733307d in _start (/srv/scratch/z5500277/target/exiv2/build-asan/bin/exiv2+0xa407d)

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /srv/scratch/z5500277/target/exiv2/src/types.cpp:582:33 in
Aborted

Expected behavior

I think we an add a small check at line 581 to fix it.

Desktop (please complete the following information):

  • OS and version: Linux
  • Exiv2 version and source: master
  • Compiler and version: Gcc 12.2
  • Compilation mode and/or compiler flags: "-O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer" -DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address,undefined" -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined "

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions