From 7bf3c422a9bd83b096985ef30e23a976c6d699bb Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Tue, 26 Dec 2023 11:29:47 -0500 Subject: [PATCH] Fix buffer overflows when reading invalid GPS data --- exif.cpp | 28 +++++++++++++++++++++++++++ test-images/gps-invalid.jpg | Bin 0 -> 800 bytes test-images/gps-invalid.jpg.expected | 1 + 3 files changed, 29 insertions(+) create mode 100644 test-images/gps-invalid.jpg create mode 100644 test-images/gps-invalid.jpg.expected diff --git a/exif.cpp b/exif.cpp index 9a7356b..6ca9c07 100644 --- a/exif.cpp +++ b/exif.cpp @@ -945,6 +945,10 @@ easyexif::ParseError easyexif::EXIFInfo::parseFromEXIFSegment( switch (tag) { case 1: // GPS north or south + if (offs + 8 > len) { + return easyexif::ParseError::DataCorrupt; + } + GeoLocation.LatComponents.direction = *(buf + offs + 8); if (GeoLocation.LatComponents.direction == 0) { @@ -960,6 +964,10 @@ easyexif::ParseError easyexif::EXIFInfo::parseFromEXIFSegment( // GPS latitude if ((format == UnsignedRational || format == SignedRational) && length == 3) { + if (data + tiff_header_start + 16 > len) { + return easyexif::ParseError::DataCorrupt; + } + GeoLocation.LatComponents.degrees = parse_value( buf + data + tiff_header_start, alignIntel); @@ -981,6 +989,10 @@ easyexif::ParseError easyexif::EXIFInfo::parseFromEXIFSegment( case 3: // GPS east or west + if (offs + 8 > len) { + return easyexif::ParseError::DataCorrupt; + } + GeoLocation.LonComponents.direction = *(buf + offs + 8); if (GeoLocation.LonComponents.direction == 0) { @@ -996,6 +1008,10 @@ easyexif::ParseError easyexif::EXIFInfo::parseFromEXIFSegment( // GPS longitude if ((format == UnsignedRational || format == SignedRational) && length == 3) { + if (data + tiff_header_start + 16 > len) { + return easyexif::ParseError::DataCorrupt; + } + GeoLocation.LonComponents.degrees = parse_value( buf + data + tiff_header_start, alignIntel); @@ -1016,6 +1032,10 @@ easyexif::ParseError easyexif::EXIFInfo::parseFromEXIFSegment( case 5: // GPS altitude reference (below or above sea level) + if (offs + 8 > len) { + return easyexif::ParseError::DataCorrupt; + } + GeoLocation.AltitudeRef = *(buf + offs + 8); if (1 == GeoLocation.AltitudeRef) { @@ -1026,6 +1046,10 @@ easyexif::ParseError easyexif::EXIFInfo::parseFromEXIFSegment( case 6: // GPS altitude if (format == UnsignedRational || format == SignedRational) { + if (data + tiff_header_start > len) { + return easyexif::ParseError::DataCorrupt; + } + GeoLocation.Altitude = parse_value( buf + data + tiff_header_start, alignIntel); @@ -1038,6 +1062,10 @@ easyexif::ParseError easyexif::EXIFInfo::parseFromEXIFSegment( case 11: // GPS degree of precision (DOP) if (format == UnsignedRational || format == SignedRational) { + if (data + tiff_header_start > len) { + return easyexif::ParseError::DataCorrupt; + } + GeoLocation.DOP = parse_value( buf + data + tiff_header_start, alignIntel); } diff --git a/test-images/gps-invalid.jpg b/test-images/gps-invalid.jpg new file mode 100644 index 0000000000000000000000000000000000000000..75d215db25b0a0bd7a24d3388505a1479c872763 GIT binary patch literal 800 zcmex=Bm<7<_#hv=|r|I2gDX`5BmiEH)r+V-x_hxq$2*MkxkXAk7HG z(-@`U?0JkD49sA0pe{y3xZY)qMqsuGP;L#AFjNgtcY7uS3)Gwg9jY)klN(Ts!Lgtq zCzT;HAR|97Rly_}B;*0aAUnadnVx~3A%l^Dp^+6385t`Wnpl~bTbWogFi14bg1L$D zS<_rN`(1|;!hId;P<8+V!vqEfcA&W|21Z7P6PRIcW&AdQ1;%FLn#c%I19HP8Mqt>0 z-NGa{i3w&tliDO^22l6_rI_?4u|v%VhSVfZC|dx?=7Os?nOGw@U7a?&`M8hqhD(!jcS!%<@FK?B*Npew)|P%dKb6UwS`R#$78T^Qgt Sk7s;x3~*iFmuP14|0VzugNO0} literal 0 HcmV?d00001 diff --git a/test-images/gps-invalid.jpg.expected b/test-images/gps-invalid.jpg.expected new file mode 100644 index 0000000..747afa5 --- /dev/null +++ b/test-images/gps-invalid.jpg.expected @@ -0,0 +1 @@ +Error parsing EXIF: code 1985