From 18c0e1a1f05e55e666db739519f031f79d8347a8 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Tue, 27 Feb 2024 22:05:05 +1300
Subject: [PATCH 2/2] Fix theoretical overflow in Windows pg_pread/pg_pwrite.

We don't really expect anything in PostgreSQL to call these functions
with gigabytes of data, but in theory if they did, the conversion of the
size argument to DWORD, or of the return value to ssize_t on 32 bit
systems could overflow.

Apply an artificial cap of very large size.  Hypothetical callers
working in very large sizes expect to deal with short transfers.  The
right cap here might arguably be Min(SSIZE_MAX, DWORD_MAX), but Windows
doesn't define those, and perhaps it's better to have a nicely aligned
number for some reason, so let's go with 1GB.

The pg_preadv/pg_pwritev functions in port/pg_iovec.h will inherit this
behavior.

Discussion: https://postgr.es/m/1672202.1703441340%40sss.pgh.pa.us
---
 src/port/win32pread.c  | 3 +++
 src/port/win32pwrite.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/src/port/win32pread.c b/src/port/win32pread.c
index e1a066fdbe..baad5d66d9 100644
--- a/src/port/win32pread.c
+++ b/src/port/win32pread.c
@@ -30,6 +30,9 @@ pg_pread(int fd, void *buf, size_t size, off_t offset)
 		return -1;
 	}
 
+	/* Avoid overflowing DWORD or ssize_t with an artificial cap. */
+	size = Min(size, 1024 * 1024 * 1024);
+
 	/* Note that this changes the file position, despite not using it. */
 	overlapped.Offset = offset;
 	if (!ReadFile(handle, buf, size, &result, &overlapped))
diff --git a/src/port/win32pwrite.c b/src/port/win32pwrite.c
index c54bf041bf..d1acd363ba 100644
--- a/src/port/win32pwrite.c
+++ b/src/port/win32pwrite.c
@@ -30,6 +30,9 @@ pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
 		return -1;
 	}
 
+	/* Avoid overflowing DWORD or ssize_t with an artificial cap. */
+	size = Min(size, 1024 * 1024 * 1024);
+
 	/* Note that this changes the file position, despite not using it. */
 	overlapped.Offset = offset;
 	if (!WriteFile(handle, buf, size, &result, &overlapped))
-- 
2.39.3 (Apple Git-145)

