mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 23:56:58 +03:00
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 c50b7c09d; backpatch to 9.4 where that was introduced. Tom Lane and Michael Paquier Security: CVE-2017-7548
This commit is contained in:
parent
36f9f60958
commit
873741c682
@ -898,6 +898,18 @@ lo_put(PG_FUNCTION_ARGS)
|
|||||||
CreateFSContext();
|
CreateFSContext();
|
||||||
|
|
||||||
loDesc = inv_open(loOid, INV_WRITE, fscxt);
|
loDesc = inv_open(loOid, INV_WRITE, fscxt);
|
||||||
|
|
||||||
|
/* Permission check */
|
||||||
|
if (!lo_compat_privileges &&
|
||||||
|
pg_largeobject_aclcheck_snapshot(loDesc->id,
|
||||||
|
GetUserId(),
|
||||||
|
ACL_UPDATE,
|
||||||
|
loDesc->snapshot) != ACLCHECK_OK)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
|
errmsg("permission denied for large object %u",
|
||||||
|
loDesc->id)));
|
||||||
|
|
||||||
inv_seek(loDesc, offset, SEEK_SET);
|
inv_seek(loDesc, offset, SEEK_SET);
|
||||||
written = inv_write(loDesc, VARDATA_ANY(str), VARSIZE_ANY_EXHDR(str));
|
written = inv_write(loDesc, VARDATA_ANY(str), VARSIZE_ANY_EXHDR(str));
|
||||||
Assert(written == VARSIZE_ANY_EXHDR(str));
|
Assert(written == VARSIZE_ANY_EXHDR(str));
|
||||||
|
@ -1220,6 +1220,14 @@ SELECT lo_create(2002);
|
|||||||
2002
|
2002
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT loread(lo_open(1001, x'20000'::int), 32); -- allowed, for now
|
||||||
|
loread
|
||||||
|
--------
|
||||||
|
\x
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT lowrite(lo_open(1001, x'40000'::int), 'abcd'); -- fail, wrong mode
|
||||||
|
ERROR: large object descriptor 0 was not opened for writing
|
||||||
SELECT loread(lo_open(1001, x'40000'::int), 32);
|
SELECT loread(lo_open(1001, x'40000'::int), 32);
|
||||||
loread
|
loread
|
||||||
--------
|
--------
|
||||||
@ -1315,6 +1323,8 @@ SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
|
|||||||
ERROR: permission denied for large object 1002
|
ERROR: permission denied for large object 1002
|
||||||
SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); -- to be denied
|
SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); -- to be denied
|
||||||
ERROR: permission denied for large object 1002
|
ERROR: permission denied for large object 1002
|
||||||
|
SELECT lo_put(1002, 1, 'abcd'); -- to be denied
|
||||||
|
ERROR: permission denied for large object 1002
|
||||||
SELECT lo_unlink(1002); -- to be denied
|
SELECT lo_unlink(1002); -- to be denied
|
||||||
ERROR: must be owner of large object 1002
|
ERROR: must be owner of large object 1002
|
||||||
SELECT lo_export(1001, '/dev/null'); -- to be denied
|
SELECT lo_export(1001, '/dev/null'); -- to be denied
|
||||||
|
@ -770,6 +770,9 @@ SET SESSION AUTHORIZATION regressuser2;
|
|||||||
SELECT lo_create(2001);
|
SELECT lo_create(2001);
|
||||||
SELECT lo_create(2002);
|
SELECT lo_create(2002);
|
||||||
|
|
||||||
|
SELECT loread(lo_open(1001, x'20000'::int), 32); -- allowed, for now
|
||||||
|
SELECT lowrite(lo_open(1001, x'40000'::int), 'abcd'); -- fail, wrong mode
|
||||||
|
|
||||||
SELECT loread(lo_open(1001, x'40000'::int), 32);
|
SELECT loread(lo_open(1001, x'40000'::int), 32);
|
||||||
SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
|
SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
|
||||||
SELECT loread(lo_open(1003, x'40000'::int), 32);
|
SELECT loread(lo_open(1003, x'40000'::int), 32);
|
||||||
@ -809,6 +812,7 @@ SET SESSION AUTHORIZATION regressuser4;
|
|||||||
SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
|
SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
|
||||||
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
|
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
|
||||||
SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); -- to be denied
|
SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); -- to be denied
|
||||||
|
SELECT lo_put(1002, 1, 'abcd'); -- to be denied
|
||||||
SELECT lo_unlink(1002); -- to be denied
|
SELECT lo_unlink(1002); -- to be denied
|
||||||
SELECT lo_export(1001, '/dev/null'); -- to be denied
|
SELECT lo_export(1001, '/dev/null'); -- to be denied
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user