BUG #14931: Unchecked attnum value in ATExecAlterColumnType()

Started by PanBianover 8 years ago2 messagesbugs
Jump to latest
#1PanBian
bianpan2016@163.com

The following bug has been logged on the website:

Bug reference: 14931
Logged by: Pan Bian
Email address: bianpan2016@163.com
PostgreSQL version: 10.1
Operating system: Linux
Description:

File: src/backend/commands/tablecmds.c
Function: ATExecAlterColumnType
Line: 8986

The value of field attTup->attnum may be zero or even negative. However, in
function ATExecAlterColumnType(), its value is incorrectly assumed to be
larger than or equal to 1. In an exceptional case, it may lead to a buffer
overflow bug (see lines 8989 and 8990).

For your convenience, I copy and paste related codes as follows:

8978 /* Look up the target column */
8979 heapTup = SearchSysCacheCopyAttName(RelationGetRelid(rel),
colName);
8980 if (!HeapTupleIsValid(heapTup)) /* shouldn't happen */
8981 ereport(ERROR,
8982 (errcode(ERRCODE_UNDEFINED_COLUMN),
8983 errmsg("column \"%s\" of relation \"%s\" does not
exist",
8984 colName, RelationGetRelationName(rel))));
8985 attTup = (Form_pg_attribute) GETSTRUCT(heapTup);
8986 attnum = attTup->attnum;
8987
8988 /* Check for multiple ALTER TYPE on same column --- can't cope
*/
8989 if (attTup->atttypid != tab->oldDesc->attrs[attnum - 1]->atttypid
||
8990 attTup->atttypmod != tab->oldDesc->attrs[attnum -
1]->atttypmod)
8991 ereport(ERROR,
8992 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8993 errmsg("cannot alter type of column \"%s\" twice",
8994 colName)));

I also collect a function (i.e. ATExecDropNotNull) in the same file as an
example, shown as follows:

5616 tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel),
colName);
5617
5618 if (!HeapTupleIsValid(tuple))
5619 ereport(ERROR,
5620 (errcode(ERRCODE_UNDEFINED_COLUMN),
5621 errmsg("column \"%s\" of relation \"%s\" does not
exist",
5622 colName, RelationGetRelationName(rel))));
5623
5624 attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
5625
5626 /* Prevent them from altering a system attribute */
5627 if (attnum <= 0)
5628 ereport(ERROR,
5629 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5630 errmsg("cannot alter system column \"%s\"",
5631 colName)));

Thank you!

Pan Bian

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: PanBian (#1)
Re: BUG #14931: Unchecked attnum value in ATExecAlterColumnType()

bianpan2016@163.com writes:

File: src/backend/commands/tablecmds.c
Function: ATExecAlterColumnType
Line: 8986

The value of field attTup->attnum may be zero or even negative. However, in
function ATExecAlterColumnType(), its value is incorrectly assumed to be
larger than or equal to 1. In an exceptional case, it may lead to a buffer
overflow bug (see lines 8989 and 8990).

I do not think this is a real problem, because ATPrepAlterColumnType
has already checked for attnum <= 0 (at line 8826, in HEAD). If
ATExecAlterColumnType can't assume that ATPrepAlterColumnType has
already been run, we have more problems than this.

I also collect a function (i.e. ATExecDropNotNull) in the same file as an
example, shown as follows:

The division of labor between Prep and Exec functions isn't very uniform
in this file. That may not be a great thing stylistically, but if we
decide it's something to improve, it'd have to be done holistically not
one point at a time.

regards, tom lane