v1-0001-Fix-refint-cascade-UPDATE-crash-with-NULL-keys.patch
application/octet-stream
Filename: v1-0001-Fix-refint-cascade-UPDATE-crash-with-NULL-keys.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1-0001
Subject: Fix refint cascade UPDATE crash with NULL keys
| File | + | − |
|---|---|---|
| contrib/spi/refint.c | 15 | 5 |
From dd97dd1e196aa8dd0a12afb957b046d984ed491e Mon Sep 17 00:00:00 2001
From: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Date: Tue, 12 May 2026 17:43:12 +0000
Subject: [PATCH v1 1/2] Fix refint cascade UPDATE crash with NULL keys
check_foreign_key() builds cascade UPDATE queries using the new key
value retrieved by SPI_getvalue(). When that value is NULL,
SPI_getvalue() returns a NULL pointer, which the code then passed to
snprintf("%s"). That is undefined behavior; on most builds it happens
to print "(null)", which SQL then parses as the NULL keyword, but on
builds with _FORTIFY_SOURCE the snprintf formatter crashes when
computing the string length, matching the backtrace in the report.
Emit the SQL NULL keyword directly when SPI_getvalue() returns NULL.
No regression test is added because triggering the crash requires a
hardened libc; without that, the existing code already happens to
produce the correct result via the "(null)" substitution above.
Reported-by: Nikita Kalinin <n.kalinin@postgrespro.ru>
Discussion: https://postgr.es/m/19476-bd04ea6241345303@postgresql.org
---
contrib/spi/refint.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/contrib/spi/refint.c b/contrib/spi/refint.c
index fbbd558ca1e..0063410f27e 100644
--- a/contrib/spi/refint.c
+++ b/contrib/spi/refint.c
@@ -496,12 +496,22 @@ check_foreign_key(PG_FUNCTION_ARGS)
#endif
/*
- * is_char_type =1 i set ' ' for define a new value
+ * is_char_type =1 i set ' ' for define a new value.
+ *
+ * SPI_getvalue() returns NULL for SQL NULL values, so
+ * emit the NULL keyword rather than passing a NULL
+ * pointer to snprintf("%s"), which is undefined
+ * behavior.
*/
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql),
- " %s = %s%s%s %s ",
- args2[k], (is_char_type > 0) ? "'" : "",
- nv, (is_char_type > 0) ? "'" : "", (k < nkeys) ? ", " : "");
+ if (nv == NULL)
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql),
+ " %s = NULL %s ",
+ args2[k], (k < nkeys) ? ", " : "");
+ else
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql),
+ " %s = %s%s%s %s ",
+ args2[k], (is_char_type > 0) ? "'" : "",
+ nv, (is_char_type > 0) ? "'" : "", (k < nkeys) ? ", " : "");
}
strcat(sql, " where ");
}
--
2.43.0