Coordinated Disclosure Timeline
- 2025-01-09: Issue reported at https://gitlab.freedesktop.org/libopenraw/exempi/-/issues/33
- 2025-01-09: Issue reported to psirt@adobe.com
- 2025-02-04: Issue acknowledged by Adobe
- 2025-03-28: Fixed in release v2025.03 at https://github.com/adobe/XMP-Toolkit-SDK/releases/tag/v2025.03
- 2025-04-08: Security bulletin published https://helpx.adobe.com/security/products/xmpcore/apsb25-34.html
Summary
During our research on Exempi, we identified five vulnerabilities affecting the Adobe XMP-Toolkit-SDK. These vulnerabilities were reported to both Adobe CSIRT and the Exempi project.
Project
- Adobe XMP-Toolkit-SDK
- Exempi
Tested Version
- Adobe XMP-Toolkit-SDK v2023.12
- Exempi 2.6.5
Details
Issue 1: OOB Read in TrimTrailingSpaces (GHSL-2024-083
)
The TrimTrailingSpaces
function is susceptible to an out-of-bounds read due to an invalid length parameter passed to the function.
Under certain circumstances, the origLen
variable can store an incorrect value. This causes the lastChar
pointer to point to an incorrect address.
As a result, the function attempts to access memory beyond the allocated buffer.
static size_t TrimTrailingSpaces ( char * firstChar, size_t origLen ){
…
char * lastChar = firstChar + origLen - 1;
if ( (*lastChar != ' ') && (*lastChar != 0) ) return origLen;
…
Issue 2: OOB read in ASF_Support::ReadHeaderObject (GHSL-2024-084
)
The ReadHeaderObject
method in ASF_Support
, responsible for reading ASF file headers, can access memory beyond the allocated buffer under certain circumstances.
Here’s how the issue occurs:
- The method reads the header data of the ASF file into an
ASF_ObjectBase
object. - It then allocates a dynamic buffer based on the
objectBase.size
property. - If
objectBase.size
is incorrect, the allocation might fail, resulting in a smaller buffer than expected. - Subsequent attempts to access the buffer at fixed positions can cause out-of-bounds reads due to the insufficient buffer size.
bool ASF_Support::ReadHeaderObject ( XMP_IO* fileRef, ObjectState& inOutObjectState, const ObjectData& newObject ){
…
ASF_ObjectBase objectBase;
…
if ( kASF_ObjectBaseLen != fileRef->Read ( &objectBase, kASF_ObjectBaseLen, true ) )
…
buffer.reserve ( XMP_Uns32( objectBase.size ) );
…
XMP_Uns32 flags = GetUns32LE ( &buffer[88] );
…
Issue 3: Multiple OOB read vulns in MPEG4_MetaHandler::ParseTimecodeTrack (GHSL-2024-085
)
The ParseTimecodeTrack
method doesn’t correctly check the boundaries of the trailerPos
and textPtr
pointers.
As a result, it can read up to 10 bytes beyond the allocated memory.
There are multiple parts of the code where this bug can be triggered
bool MPEG4_MetaHandler::ParseTimecodeTrack(){
…
trailerNext = ISOMedia::GetBoxInfo ( trailerPos, trailerLimit, &trailerInfo );
…
this->tmcdInfo.macLang = GetUns16BE ( trailerPos + trailerInfo.headerSize + 2 );
…
this->tmcdInfo.macName.assign ( textPtr, textLen );
…
sampleOffset = GetUns32BE ( &stcoPtr[firstChunkNumber-1] );
Issue 4: Out of bounds call to strlen in ImportConversionTable (GHSL-2024-086
)
The ImportConversionTable
function contains an out-of-bounds memory access bug. This vulnerability stems from improper control of the bytePtr
pointer.
As a result, the function strlen
might try to determine the length of invalid data.
static void
ImportConversionTable ( const TIFF_Manager::TagInfo & tagInfo, bool nativeEndian,
SXMPMeta * xmp, const char * xmpNS, const char * xmpProp ){
…
size_t nameLen = strlen((XMP_StringPtr)bytePtr) + 1;
…
Issue 5: Non-null terminated string leading to OOB Read in XMPMeta::SetLocalizedText (GHSL-2024-087
)
The SetLocalizedText
method is susceptible to an out-of-bounds (OOB) read when a non-null terminated XMP_StringPtr
argument is passed. XMP_StringPtr
is in fact, a const char pointer:
typedef const char * XMP_StringPtr; // Points to a null terminated UTF-8 string.
This can cause the program to attempt to read beyond the allocated memory buffer in multiple places throughout the code.
In the following code snippet we show how the program throws an OOB when it tries to convert the C string to std::string
through the basic_string& operator=
void XMP_Node::SetValue( XMP_StringPtr _value ){
…
std::string newValue = _value;
…
CVE
- CVE-2025-30305
- CVE-2025-30306
- CVE-2025-30307
- CVE-2025-30308
- CVE-2025-30309
Credit
These issues were discovered and reported by GHSL team member @antonio-morales (Antonio Morales).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2024-083
, GHSL-2024-084
, GHSL-2024-085
, GHSL-2024-086
, or GHSL-2024-087
in any communication regarding these issues.