Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 52a4143

Browse files
committed
Require update permission for the large object written by lo_put().
lo_put() surely should require UPDATE permission, the same as lowrite(), but it failed to check for that, as reported by Chapman Flack. Oversight in commit c50b7c0; backpatch to 9.4 where that was introduced. Tom Lane and Michael Paquier Security: CVE-2017-7548
1 parent 1560996 commit 52a4143

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

src/backend/libpq/be-fsstubs.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,18 @@ lo_put(PG_FUNCTION_ARGS)
896896
CreateFSContext();
897897

898898
loDesc = inv_open(loOid, INV_WRITE, fscxt);
899+
900+
/* Permission check */
901+
if (!lo_compat_privileges &&
902+
pg_largeobject_aclcheck_snapshot(loDesc->id,
903+
GetUserId(),
904+
ACL_UPDATE,
905+
loDesc->snapshot) != ACLCHECK_OK)
906+
ereport(ERROR,
907+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
908+
errmsg("permission denied for large object %u",
909+
loDesc->id)));
910+
899911
inv_seek(loDesc, offset, SEEK_SET);
900912
written = inv_write(loDesc, VARDATA_ANY(str), VARSIZE_ANY_EXHDR(str));
901913
Assert(written == VARSIZE_ANY_EXHDR(str));

src/test/regress/expected/privileges.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,14 @@ SELECT lo_create(2002);
12191219
2002
12201220
(1 row)
12211221

1222+
SELECT loread(lo_open(1001, x'20000'::int), 32); -- allowed, for now
1223+
loread
1224+
--------
1225+
\x
1226+
(1 row)
1227+
1228+
SELECT lowrite(lo_open(1001, x'40000'::int), 'abcd'); -- fail, wrong mode
1229+
ERROR: large object descriptor 0 was not opened for writing
12221230
SELECT loread(lo_open(1001, x'40000'::int), 32);
12231231
loread
12241232
--------
@@ -1314,6 +1322,8 @@ SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
13141322
ERROR: permission denied for large object 1002
13151323
SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); -- to be denied
13161324
ERROR: permission denied for large object 1002
1325+
SELECT lo_put(1002, 1, 'abcd'); -- to be denied
1326+
ERROR: permission denied for large object 1002
13171327
SELECT lo_unlink(1002); -- to be denied
13181328
ERROR: must be owner of large object 1002
13191329
SELECT lo_export(1001, '/dev/null'); -- to be denied

src/test/regress/sql/privileges.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,9 @@ SET SESSION AUTHORIZATION regress_user2;
770770
SELECT lo_create(2001);
771771
SELECT lo_create(2002);
772772

773+
SELECT loread(lo_open(1001, x'20000'::int), 32); -- allowed, for now
774+
SELECT lowrite(lo_open(1001, x'40000'::int), 'abcd'); -- fail, wrong mode
775+
773776
SELECT loread(lo_open(1001, x'40000'::int), 32);
774777
SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
775778
SELECT loread(lo_open(1003, x'40000'::int), 32);
@@ -809,6 +812,7 @@ SET SESSION AUTHORIZATION regress_user4;
809812
SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
810813
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
811814
SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); -- to be denied
815+
SELECT lo_put(1002, 1, 'abcd'); -- to be denied
812816
SELECT lo_unlink(1002); -- to be denied
813817
SELECT lo_export(1001, '/dev/null'); -- to be denied
814818

0 commit comments

Comments
 (0)