public inbox for [email protected]  
help / color / mirror / Atom feed
From: Jacob Champion <[email protected]>
To: Daniel Gustafsson <[email protected]>
Cc: Andres Freund <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Subject: Re: oauth integer overflow
Date: Thu, 23 Apr 2026 11:31:34 -0700
Message-ID: <CAOYmi+k6K6VKTZLPtQLHnoSSMRZfH_=x6bHRUC3zf1F9kjyb1Q@mail.gmail.com> (raw)
In-Reply-To: <[email protected]>
References: <qtclihmrkq67ach3xjxyi4qcksstin5qxwsnkqefkmotxwh4g6@ae2bj6jvcmry>
	<[email protected]>
	<CAOYmi+n4U_g+k1Bfs2eavJdps0qQj3HFDa5i3V1c0m3CLYUWhA@mail.gmail.com>
	<[email protected]>

On Thu, Apr 23, 2026 at 11:17 AM Daniel Gustafsson <[email protected]> wrote:
> > Cool. I have one written up and can share it for comparison, if you'd
> > like, but it's fairly verbose and I wonder if there's a better way to
> > do it.
>
> Well, if you're already done then please do share it, and we'll use that as a
> starting point.

Attached. The static_assert for the millisecond calculation is the
only part I don't really like, but doing an overflow check on a
calculation that can't overflow int64 is even more verbose/wasteful.

--Jacob


Attachments:

  [application/octet-stream] 0001-libpq-oauth-Avoid-overflow-for-very-large-intervals.patch (2.9K, 2-0001-libpq-oauth-Avoid-overflow-for-very-large-intervals.patch)
  download | inline diff:
From 27de39f667ab12b78778142fe60e6376f4d49ec3 Mon Sep 17 00:00:00 2001
From: Jacob Champion <[email protected]>
Date: Thu, 23 Apr 2026 09:46:42 -0700
Subject: [PATCH] libpq-oauth: Avoid overflow for very large intervals

---
 src/interfaces/libpq-oauth/oauth-curl.c | 38 ++++++++++++++++++-------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/src/interfaces/libpq-oauth/oauth-curl.c b/src/interfaces/libpq-oauth/oauth-curl.c
index abbef93f95f..70cc4710b59 100644
--- a/src/interfaces/libpq-oauth/oauth-curl.c
+++ b/src/interfaces/libpq-oauth/oauth-curl.c
@@ -28,6 +28,7 @@
 #error libpq-oauth is not supported on this platform
 #endif
 
+#include "common/int.h"
 #include "common/jsonapi.h"
 #include "mb/pg_wchar.h"
 #include "oauth-curl.h"
@@ -136,7 +137,7 @@ struct device_authz
 
 	/* Fields below are parsed from the corresponding string above. */
 	int			expires_in;
-	int			interval;
+	int32		interval;
 };
 
 static void
@@ -1020,7 +1021,7 @@ parse_json_number(const char *s)
  * expensive network polling loop.) Tests may remove the lower bound with
  * PGOAUTHDEBUG, for improved performance.
  */
-static int
+static int32
 parse_interval(struct async_ctx *actx, const char *interval_str)
 {
 	double		parsed;
@@ -1031,8 +1032,8 @@ parse_interval(struct async_ctx *actx, const char *interval_str)
 	if (parsed < 1)
 		return (actx->debug_flags & OAUTHDEBUG_UNSAFE_DOS_ENDPOINT) ? 0 : 1;
 
-	else if (parsed >= INT_MAX)
-		return INT_MAX;
+	else if (parsed >= INT32_MAX)
+		return INT32_MAX;
 
 	return parsed;
 }
@@ -2620,10 +2621,7 @@ handle_token_response(struct async_ctx *actx, char **token)
 	 */
 	if (strcmp(err->error, "slow_down") == 0)
 	{
-		int			prev_interval = actx->authz.interval;
-
-		actx->authz.interval += 5;
-		if (actx->authz.interval < prev_interval)
+		if (pg_add_s32_overflow(actx->authz.interval, 5, &actx->authz.interval))
 		{
 			actx_error(actx, "slow_down interval overflow");
 			goto token_cleanup;
@@ -2949,8 +2947,28 @@ pg_fe_run_oauth_flow_impl(PGconn *conn, PGoauthBearerRequestV2 *request,
 				 * Wait for the required interval before issuing the next
 				 * request.
 				 */
-				if (!set_timer(actx, actx->authz.interval * 1000))
-					goto error_return;
+				{
+					/*
+					 * LONG_MAX milliseconds is 24 days on 32-bit platforms,
+					 * which for most people is going to be equivalent to a
+					 * disabled timer... but avoid overflow in case the
+					 * compiler does something unintuitive.
+					 */
+					int64		interval_ms;
+
+					/*
+					 * If you trip over this, the multiplication here needs to
+					 * be adjusted for overflow too.
+					 */
+					static_assert(sizeof(actx->authz.interval) <= 4);
+
+					interval_ms = actx->authz.interval * ((int64) 1000);
+					if (interval_ms > LONG_MAX)
+						interval_ms = LONG_MAX;
+
+					if (!set_timer(actx, (long) interval_ms))
+						goto error_return;
+				}
 
 				/*
 				 * No Curl requests are running, so we can simplify by having
-- 
2.34.1



view thread (10+ messages)  latest in thread

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: [email protected]
  Cc: [email protected], [email protected], [email protected]
  Subject: Re: oauth integer overflow
  In-Reply-To: <CAOYmi+k6K6VKTZLPtQLHnoSSMRZfH_=x6bHRUC3zf1F9kjyb1Q@mail.gmail.com>

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

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