pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Laurenz Albe <laurenz.albe@cybertec.at>
To: exclusion@gmail.com
To: pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #18200: Undefined behaviour in interval_div
Date: Wed, 15 Nov 2023 18:23:08 +0100
Message-ID: <c8374b1627add66a9593de562be16142cd690095.camel@cybertec.at> (raw)
In-Reply-To: <18200-5ea288c7b2d504b1@postgresql.org>
References: <18200-5ea288c7b2d504b1@postgresql.org>

On Wed, 2023-11-15 at 13:00 +0000, PG Bug reporting form wrote:
> The following query:
> SELECT interval '12000000 months' / 0.001;
> 
> triggers an ubsan-detected error:
> timestamp.c:3408:18: runtime error: 1.2e+10 is outside the range of
> representable values of type 'int'
> 
> Without ubsan the result is:
>  -178956970 years -8 mons -2562047788:00:54.775808

How about the attached fix?

Yours,
Laurenz Albe

Attachments:

  [text/x-patch] 0001-Check-for-overflow-in-interval-division.patch (1.2K, ../c8374b1627add66a9593de562be16142cd690095.camel@cybertec.at/2-0001-Check-for-overflow-in-interval-division.patch)
  download | inline diff:
From 2748c01a3e343001d3668554fdb7ee894fefbdf1 Mon Sep 17 00:00:00 2001
From: Laurenz Albe <laurenz.albe@cybertec.at>
Date: Wed, 15 Nov 2023 18:21:42 +0100
Subject: [PATCH] Check for overflow in interval division

Dividing a large interval by a small floating point number
can lead to integer overflow, which results in bogus values.
Report by Alexander Lakhin.

Discussion: https://postgr.es/m/18200-5ea288c7b2d504b1@postgresql.org
---
 src/backend/utils/adt/timestamp.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 647b97aca6..b21efeb897 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -3422,6 +3422,15 @@ interval_div(PG_FUNCTION_ARGS)
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
 
+	/* check for overflow */
+	if (span->month / factor > PG_INT32_MAX ||
+		span->month / factor < PG_INT32_MIN ||
+		span->day / factor > PG_INT32_MAX ||
+		span->day / factor < PG_INT32_MIN)
+	ereport(ERROR,
+			errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+			errmsg("interval out of range"));
+
 	result->month = (int32) (span->month / factor);
 	result->day = (int32) (span->day / factor);
 
-- 
2.41.0



view thread (5+ messages)  latest in thread

Message-ID: <c8374b1627add66a9593de562be16142cd690095.camel@cybertec.at>
Permalink:  ../c8374b1627add66a9593de562be16142cd690095.camel@cybertec.at/
Also on:    postgresql.org/message-id/c8374b1627add66a9593de562be16142cd690095.camel@cybertec.at

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-bugs@postgresql.org
  Cc: laurenz.albe@cybertec.at, exclusion@gmail.com, pgsql-bugs@lists.postgresql.org
  Subject: Re: BUG #18200: Undefined behaviour in interval_div
  In-Reply-To: <c8374b1627add66a9593de562be16142cd690095.camel@cybertec.at>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox