From 3e1338475ffc2eac25de60a9de9ce689b763aced Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvherre@alvh.no-ip.org> Date: Mon, 28 Mar 2016 10:57:42 -0300 Subject: [PATCH] Add missing checks to some of pageinspect's BRIN functions brin_page_type() and brin_metapage_info() did not enforce being called by superuser, like other pageinspect functions that take bytea do. Since they don't verify the passed page thoroughly, it is possible to use them to read the server memory with a carefully crafted bytea value, up to a file kilobytes from where the input bytea is located. Have them throw errors if called by a non-superuser. Report and initial patch: Andreas Seltenreich Security: CVE-2016-3065 --- contrib/pageinspect/brinfuncs.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c index b2e266c9f07..aa6bd0bc978 100644 --- a/contrib/pageinspect/brinfuncs.c +++ b/contrib/pageinspect/brinfuncs.c @@ -46,8 +46,23 @@ brin_page_type(PG_FUNCTION_ARGS) { bytea *raw_page = PG_GETARG_BYTEA_P(0); Page page = VARDATA(raw_page); + int raw_page_size; char *type; + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be superuser to use raw page functions")))); + + raw_page_size = VARSIZE(raw_page) - VARHDRSZ; + + if (raw_page_size != BLCKSZ) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("input page too small"), + errdetail("Expected size %d, got %d", + BLCKSZ, raw_page_size))); + switch (BrinPageType(page)) { case BRIN_PAGETYPE_META: @@ -79,11 +94,12 @@ verify_brin_page(bytea *raw_page, uint16 type, const char *strtype) raw_page_size = VARSIZE(raw_page) - VARHDRSZ; - if (raw_page_size < SizeOfPageHeaderData) + if (raw_page_size != BLCKSZ) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("input page too small"), - errdetail("Expected size %d, got %d", raw_page_size, BLCKSZ))); + errdetail("Expected size %d, got %d", + BLCKSZ, raw_page_size))); page = VARDATA(raw_page); @@ -316,6 +332,11 @@ brin_metapage_info(PG_FUNCTION_ARGS) bool nulls[4]; HeapTuple htup; + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be superuser to use raw page functions")))); + page = verify_brin_page(raw_page, BRIN_PAGETYPE_META, "metapage"); /* Build a tuple descriptor for our result type */ -- GitLab