Skip to content

Widen the postgres interval month arithmetic - #5204

Draft
LucaCappelletti94 wants to merge 1 commit into
diesel-rs:mainfrom
LucaCappelletti94:fuzz-pg-interval-month-overflow
Draft

Widen the postgres interval month arithmetic#5204
LucaCappelletti94 wants to merge 1 commit into
diesel-rs:mainfrom
LucaCappelletti94:fuzz-pg-interval-month-overflow

Conversation

@LucaCappelletti94

Copy link
Copy Markdown
Member

FromSql<Interval, Pg> for chrono::Duration computes interval.months * DAYS_PER_MONTH + interval.days in i32, and all three fields arrive off the wire, so a well formed 16 byte interval is enough to overflow it. With debug assertions the conversion panics, and without them it wraps and the caller gets a plausible looking duration that is wrong, often with the opposite sign, where one month together with i32::MAX days reads as -185542584681600 seconds where the true value is 185542589692800.

It does not take an absurd month count either, one month is already enough once the day count is large. This is the arithmetic one line past the length check fixed in #5194, which does not touch it.

Counting the days in i64 removes the overflow without narrowing what is accepted, as the widest interval is about 66678745079 days, while chrono::Duration reaches 106751991167.

This came out of a fuzzer I am writing for diesel's deserialization code.

@LucaCappelletti94
LucaCappelletti94 force-pushed the fuzz-pg-interval-month-overflow branch from 43b1d39 to 30313c4 Compare September 5, 2026 07:14
@LucaCappelletti94
LucaCappelletti94 force-pushed the fuzz-pg-interval-month-overflow branch from 30313c4 to 58911ce Compare September 5, 2026 07:42
@weiznich
weiznich requested a review from a team September 5, 2026 09:43
Ok(Duration::days(days as i64) + Duration::microseconds(interval.microseconds))
// widened, since any `i32` month and day pair fits `i64` days and chrono
let days =
i64::from(interval.months) * i64::from(DAYS_PER_MONTH) + i64::from(interval.days);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just change the DAYS_PER_MONTH to be i64.

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.

2 participants