Add missing checks to some of pageinspect's BRIN functions
authorAlvaro Herrera <[email protected]>
Mon, 28 Mar 2016 13:57:42 +0000 (10:57 -0300)
committerAlvaro Herrera <[email protected]>
Mon, 28 Mar 2016 13:57:46 +0000 (10:57 -0300)
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

index a3d4cc5ef357ff0cc3e50b98a8101956e29dcba9..d8797833292a16eac655e75bc46a5e7392ab7ca2 100644 (file)
@@ -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 */