aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2016-03-28 10:57:42 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2016-03-28 10:57:46 -0300
commitbf78a6f107949fdfb513d1b45e30cefe04e09e4f (patch)
treeac3bc38bd83f4178d0694fccfb17bc9eb8780cdc
parentdb69e58a0642ef7fa46d62f6c4cf2460c3a1b41b (diff)
downloadpostgresql-bf78a6f107949fdfb513d1b45e30cefe04e09e4f.tar.gz
postgresql-bf78a6f107949fdfb513d1b45e30cefe04e09e4f.zip
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
-rw-r--r--contrib/pageinspect/brinfuncs.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c
index a3d4cc5ef35..d8797833292 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 */