Fix CVE-2013-0255 properly.

Revert commit ab0f7b6089 (in HEAD only)
in favor of the proper solution, which is to declare enum_recv() correctly
in the system catalogs.  It should be declared to take type "internal"
not "cstring".

Also improve the type_sanity regression test, which should have caught
this typo, so that it actually would.  Most of the relevant checks on
the signature of type I/O functions should not have been restricted to
basetypes/pseudotypes, as they should apply to any type's I/O functions.
This commit is contained in:
Tom Lane 2013-02-13 16:20:01 -05:00
parent 9728eda792
commit 71627f3d19
5 changed files with 22 additions and 19 deletions

View File

@ -18,7 +18,6 @@
#include "access/htup_details.h"
#include "catalog/indexing.h"
#include "catalog/pg_enum.h"
#include "catalog/pg_type.h"
#include "libpq/pqformat.h"
#include "utils/array.h"
#include "utils/builtins.h"
@ -105,10 +104,6 @@ enum_recv(PG_FUNCTION_ARGS)
char *name;
int nbytes;
/* guard against pre-9.3 misdeclaration of enum_recv */
if (get_fn_expr_argtype(fcinfo->flinfo, 0) == CSTRINGOID)
elog(ERROR, "invalid argument for enum_recv");
name = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
/* must check length to prevent Assert failure within SearchSysCache */

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201301231
#define CATALOG_VERSION_NO 201302131
#endif

View File

@ -4160,7 +4160,7 @@ DATA(insert OID = 3530 ( enum_range PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 22
DESCR("range between the two given enum values, as an ordered array");
DATA(insert OID = 3531 ( enum_range PGNSP PGUID 12 1 0 0 0 f f f f f f s 1 0 2277 "3500" _null_ _null_ _null_ _null_ enum_range_all _null_ _null_ _null_ ));
DESCR("range of the given enum type, as an ordered array");
DATA(insert OID = 3532 ( enum_recv PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 3500 "2275 26" _null_ _null_ _null_ _null_ enum_recv _null_ _null_ _null_ ));
DATA(insert OID = 3532 ( enum_recv PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 3500 "2281 26" _null_ _null_ _null_ _null_ enum_recv _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 3533 ( enum_send PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 17 "3500" _null_ _null_ _null_ _null_ enum_send _null_ _null_ _null_ ));
DESCR("I/O");

View File

@ -117,8 +117,10 @@ WHERE (p1.typinput = 0 OR p1.typoutput = 0);
-- Check for bogus typinput routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
WHERE p1.typinput = p2.oid AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = 'cstring'::regtype) OR
(p2.pronargs = 2 AND p2.proargtypes[0] = 'cstring'::regtype AND
p2.proargtypes[1] = 'oid'::regtype) OR
(p2.pronargs = 3 AND p2.proargtypes[0] = 'cstring'::regtype AND
p2.proargtypes[1] = 'oid'::regtype AND
p2.proargtypes[2] = 'int4'::regtype));
@ -143,7 +145,7 @@ ORDER BY 1;
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND
WHERE p1.typinput = p2.oid AND
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
(p2.oid = 'array_in'::regproc)
ORDER BY 1;
@ -184,7 +186,7 @@ ORDER BY 1;
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
WHERE p1.typoutput = p2.oid AND NOT
(p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
@ -213,8 +215,10 @@ WHERE p1.typtype = 'd' AND p1.typoutput IS DISTINCT FROM p2.typoutput;
-- Check for bogus typreceive routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT
WHERE p1.typreceive = p2.oid AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = 'internal'::regtype) OR
(p2.pronargs = 2 AND p2.proargtypes[0] = 'internal'::regtype AND
p2.proargtypes[1] = 'oid'::regtype) OR
(p2.pronargs = 3 AND p2.proargtypes[0] = 'internal'::regtype AND
p2.proargtypes[1] = 'oid'::regtype AND
p2.proargtypes[2] = 'int4'::regtype));
@ -239,7 +243,7 @@ ORDER BY 1;
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND
WHERE p1.typreceive = p2.oid AND
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
(p2.oid = 'array_recv'::regproc)
ORDER BY 1;
@ -289,7 +293,7 @@ ORDER BY 1;
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
WHERE p1.typsend = p2.oid AND NOT
(p2.prorettype = 'bytea'::regtype AND NOT p2.proretset);
oid | typname | oid | proname
-----+---------+-----+---------

View File

@ -96,8 +96,10 @@ WHERE (p1.typinput = 0 OR p1.typoutput = 0);
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
WHERE p1.typinput = p2.oid AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = 'cstring'::regtype) OR
(p2.pronargs = 2 AND p2.proargtypes[0] = 'cstring'::regtype AND
p2.proargtypes[1] = 'oid'::regtype) OR
(p2.pronargs = 3 AND p2.proargtypes[0] = 'cstring'::regtype AND
p2.proargtypes[1] = 'oid'::regtype AND
p2.proargtypes[2] = 'int4'::regtype));
@ -115,7 +117,7 @@ ORDER BY 1;
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND
WHERE p1.typinput = p2.oid AND
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
(p2.oid = 'array_in'::regproc)
ORDER BY 1;
@ -141,7 +143,7 @@ ORDER BY 1;
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
WHERE p1.typoutput = p2.oid AND NOT
(p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
-- Composites, enums, ranges should all use the same output routines
@ -159,8 +161,10 @@ WHERE p1.typtype = 'd' AND p1.typoutput IS DISTINCT FROM p2.typoutput;
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT
WHERE p1.typreceive = p2.oid AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = 'internal'::regtype) OR
(p2.pronargs = 2 AND p2.proargtypes[0] = 'internal'::regtype AND
p2.proargtypes[1] = 'oid'::regtype) OR
(p2.pronargs = 3 AND p2.proargtypes[0] = 'internal'::regtype AND
p2.proargtypes[1] = 'oid'::regtype AND
p2.proargtypes[2] = 'int4'::regtype));
@ -178,7 +182,7 @@ ORDER BY 1;
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND
WHERE p1.typreceive = p2.oid AND
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
(p2.oid = 'array_recv'::regproc)
ORDER BY 1;
@ -210,7 +214,7 @@ ORDER BY 1;
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
WHERE p1.typsend = p2.oid AND NOT
(p2.prorettype = 'bytea'::regtype AND NOT p2.proretset);
-- Composites, enums, ranges should all use the same send routines