Skip to content

Stricter rules when parsing time values to avoid UBSAN error#3148

Merged
kevinbackhouse merged 2 commits intoExiv2:mainfrom
kevinbackhouse:TimeValue-UBSAN
Feb 4, 2025
Merged

Stricter rules when parsing time values to avoid UBSAN error#3148
kevinbackhouse merged 2 commits intoExiv2:mainfrom
kevinbackhouse:TimeValue-UBSAN

Conversation

@kevinbackhouse
Copy link
Collaborator

This fixes a UBSAN error found by OSS-Fuzz: https://issues.oss-fuzz.com/issues/392928817
The error message is:

/src/exiv2/src/value.cpp:975:43: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself

It happens here:

time_.tzMinute = time_.tzHour < 0 ? -minute : minute;

The integer overflow is harmless, but I have fixed it by making the parsing rules stricter.

Stricter rules when parsing time values to avoid UBSAN error.
@kevinbackhouse
Copy link
Collaborator Author

@Mergifyio backport 0.28.x

@mergify
Copy link
Contributor

mergify bot commented Feb 4, 2025

backport 0.28.x

✅ Backports have been created

Details

// Basic format
auto tzhi = std::stoi(format.substr(0, posColon));
if (tzhi > 23)
if (tzhi < -23 || tzhi > 23)
Copy link
Collaborator

@kmilos kmilos Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could limit this (and one above) even more from -12 to 14 strictly speaking, but I guess this is just to keep the fuzzer from going to crazy...

@kevinbackhouse kevinbackhouse merged commit b917b34 into Exiv2:main Feb 4, 2025
60 checks passed
kmilos added a commit that referenced this pull request Feb 4, 2025
Stricter rules when parsing time values to avoid UBSAN error (backport #3148)
@neheb
Copy link
Collaborator

neheb commented Feb 4, 2025

@kevinbackhouse woun't it be better to use strtoul for some of these?

@kevinbackhouse
Copy link
Collaborator Author

@kevinbackhouse woun't it be better to use strtoul for some of these?

I don't think that would help, because they get written into a struct with int32_t fields:

exiv2/include/exiv2/value.hpp

Lines 1003 to 1009 in b917b34

struct Time {
int32_t hour; //!< Hour
int32_t minute; //!< Minute
int32_t second; //!< Second
int32_t tzHour; //!< Hours ahead or behind UTC
int32_t tzMinute; //!< Minutes ahead or behind UTC
};

@neheb
Copy link
Collaborator

neheb commented Feb 4, 2025

So a cast would turn negatives to 0?

@kevinbackhouse
Copy link
Collaborator Author

So a cast would turn negatives to 0?

What I mean is: if we use strtoul then we will have to cast from unsigned long to int32_t, which creates other opportunities for integer overflows, so it won't solve the problem of UBSAN errors.

Of course these integer overflows are completely harmless, and they don't happen on legitimate image files, so this PR is purely about silencing an irrelevant UBSAN error.

@kevinbackhouse kevinbackhouse deleted the TimeValue-UBSAN branch February 23, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants