On Wed, 2026-04-29 at 17:32 +0200, Laurenz Albe wrote:
> This is an attempt to get the operators from the "enum_ops" operator
> class LEAKPROOF.
>
> [...]
> 
> One particular case that I want to discuss is out-of-memory conditions.
> Some of the OOM error messages show the allocation size that failed
> (dshash.c, mbutils.c, dsa.c and mcxt.c), which could leak some
> information about the data involved.  My feeling is that that is
> something you cannot exploit just by using an application; you'd have
> to cause just the right memory pressure to make small allocations fail.
> (If we decide to err on the side of caution here, I'd actually prefer
> to have the error messages changed to not reveal the allocation size.)

I have become even less worried about that case after seeing that the
"text" comparison functions are leakproof.  With "text", one could argue
that you could trigger an OOM error by comparing with a value you don't
know, if that value has to be detoasted.  That way, you could know the
length of the unknown string.  If "text" is considered safe enough, I
don't think we need to worry about enum_cmp(), which doesn't even have
that problem.

I prepared a patch so that I can add the thread to the next commitfest.

Yours,
Laurenz Albe
From e921fd9207a6f877813e4089a654ed7a914fe311 Mon Sep 17 00:00:00 2001
From: Laurenz Albe <[email protected]>
Date: Sun, 10 May 2026 19:30:14 +0200
Subject: [PATCH v1] Mark the enum comparison functions as leakproof

The error messages reachable from enum_cmp_internal() don't
reveal anything about the compared values.  Memory allocation
errors from building a cache of the enum values also won't
give away information about the values involved.

Author: Laurenz Albe <[email protected]>
Discussion: https://postgr.es/m/8222d01be22d9d87ba1e7f47e398f4ce81af4aaf.camel%40cybertec.at
---
 src/include/catalog/pg_proc.dat          | 14 +++++++-------
 src/test/regress/expected/opr_sanity.out |  7 +++++++
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index fa9ae79082b..ef7e7b58985 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -9768,25 +9768,25 @@
   proname => 'enum_out', provolatile => 's', prorettype => 'cstring',
   proargtypes => 'anyenum', prosrc => 'enum_out' },
 { oid => '3508',
-  proname => 'enum_eq', prorettype => 'bool', proargtypes => 'anyenum anyenum',
+  proname => 'enum_eq', proleakproof => 't', prorettype => 'bool', proargtypes => 'anyenum anyenum',
   prosrc => 'enum_eq' },
 { oid => '3509',
-  proname => 'enum_ne', prorettype => 'bool', proargtypes => 'anyenum anyenum',
+  proname => 'enum_ne', proleakproof => 't', prorettype => 'bool', proargtypes => 'anyenum anyenum',
   prosrc => 'enum_ne' },
 { oid => '3510',
-  proname => 'enum_lt', prorettype => 'bool', proargtypes => 'anyenum anyenum',
+  proname => 'enum_lt', proleakproof => 't', prorettype => 'bool', proargtypes => 'anyenum anyenum',
   prosrc => 'enum_lt' },
 { oid => '3511',
-  proname => 'enum_gt', prorettype => 'bool', proargtypes => 'anyenum anyenum',
+  proname => 'enum_gt', proleakproof => 't', prorettype => 'bool', proargtypes => 'anyenum anyenum',
   prosrc => 'enum_gt' },
 { oid => '3512',
-  proname => 'enum_le', prorettype => 'bool', proargtypes => 'anyenum anyenum',
+  proname => 'enum_le', proleakproof => 't', prorettype => 'bool', proargtypes => 'anyenum anyenum',
   prosrc => 'enum_le' },
 { oid => '3513',
-  proname => 'enum_ge', prorettype => 'bool', proargtypes => 'anyenum anyenum',
+  proname => 'enum_ge', proleakproof => 't', prorettype => 'bool', proargtypes => 'anyenum anyenum',
   prosrc => 'enum_ge' },
 { oid => '3514', descr => 'less-equal-greater',
-  proname => 'enum_cmp', prorettype => 'int4', proargtypes => 'anyenum anyenum',
+  proname => 'enum_cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'anyenum anyenum',
   prosrc => 'enum_cmp' },
 { oid => '3515', descr => 'hash',
   proname => 'hashenum', prorettype => 'int4', proargtypes => 'anyenum',
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index cfdc6b1a17a..0aa48e5de81 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -855,6 +855,13 @@ sha224(bytea)
 sha256(bytea)
 sha384(bytea)
 sha512(bytea)
+enum_eq(anyenum,anyenum)
+enum_ne(anyenum,anyenum)
+enum_lt(anyenum,anyenum)
+enum_gt(anyenum,anyenum)
+enum_le(anyenum,anyenum)
+enum_ge(anyenum,anyenum)
+enum_cmp(anyenum,anyenum)
 starts_with(text,text)
 macaddr8_eq(macaddr8,macaddr8)
 macaddr8_lt(macaddr8,macaddr8)
-- 
2.54.0

Reply via email to