Hi Hackers,

It was reported in [1] that pg_dump for a user with pg_read_all_data
fails as pg_read_all_data doesn't have the permission to read large
objects. The discussion on the same thread suggested that this was an
oversight as the goal of pg_read_all_data was to allow running pg_dump
[2].

This patch proposes to fill that gap by modifying
pg_largeobject_aclmask_snapshot to provide ACL_SELECT for the role
PG_READ_ALL_DATA. Note that the patch doesn't make an equivalent
change for PG_WRITE_ALL_DATA as it would effectively provide
pg_write_all_data write access to a system catalog which is explicitly
avoided for system catalogs

Please take a look and let me know what you folks think. If this
approach makes sense, I will update the corresponding docs in the
patch.

Thanks & Regards,
Nitin Motiani
Google


[1] 
https://www.postgresql.org/message-id/19379-089536632927293f%40postgresql.org
[2] 
https://www.postgresql.org/message-id/r5a3aqlrrqen2snktdmx5tjeoakp3hmbektlqmeqhij3fqqez4%40zmx3bdscipny
From a10d85986c9ec1038fe80affea73d740c19c731e Mon Sep 17 00:00:00 2001
From: Nitin Motiani <[email protected]>
Date: Thu, 5 Feb 2026 09:08:57 +0000
Subject: [PATCH v1] Support large object functions with pg_read_all_data

* The large objects aclchk doesn't check for pg_read_all_data.
  This patch adds that support.

* Currently pg_read_all_data is able to run 'select' on pg_largeobject
  table but not able to run functions like lo_put. This change
  makes that behaviour consistent.

* We don't add support for pg_write_all_data to update large objects
  as that would end up providing write access to a system catalog
  which we currently don't provide to pg_write_all_data.
---
 src/backend/catalog/aclchk.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index a431fc0926f..36d9207672f 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -3598,6 +3598,17 @@ pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
 
 	table_close(pg_lo_meta, AccessShareLock);
 
+	/*
+	 * Check if ACL_SELECT is being checked and, if so, and not set already as
+	 * part of the result, then check if the user is a member of the
+	 * pg_read_all_data role, which allows read access to all relations. We
+	 * don't provide any write access to PG_WRITE_ALL_DATA as that would be
+	 * equivalent to providing write access to a system catalog.
+	 */
+	if (mask & ACL_SELECT && !(result & ACL_SELECT) &&
+		has_privs_of_role(roleid, ROLE_PG_READ_ALL_DATA))
+		result |= ACL_SELECT;
+
 	return result;
 }
 
-- 
2.53.0.rc2.204.g2597b5adb4-goog

Reply via email to