1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

Unbreak overflow test for attinhcount/coninhcount

Commit 90189eefc1 narrowed pg_attribute.attinhcount and
pg_constraint.coninhcount from 32 to 16 bits, but kept other related
structs with 32-bit wide fields: ColumnDef and CookedConstraint contain
an int 'inhcount' field which is itself checked for overflow on
increments, but there's no check that the values aren't above INT16_MAX
before assigning to the catalog columns.  This means that a creative
user can get a inconsistent table definition and override some
protections.

Fix it by changing those other structs to also use int16.

Also, modernize style by using pg_add_s16_overflow for overflow testing
instead of checking for negative values.

We also have Constraint.inhcount, which is here removed completely.
This was added by commit b0e96f3119 and not removed by its revert at
6f8bb7c1e9.  It is not needed by the upcoming not-null constraints
patch.

This is mostly academic, so we agreed not to backpatch to avoid ABI
problems.

Bump catversion because of the changes to parse nodes.

Co-authored-by: Álvaro Herrera <alvherre@alvh.no-ip.org>
Co-authored-by: 何建 (jian he) <jian.universality@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/202410081611.up4iyofb5ie7@alvherre.pgsql
This commit is contained in:
Álvaro Herrera
2024-10-10 17:41:01 +02:00
parent 1909835c28
commit fd64ed60b6
8 changed files with 32 additions and 32 deletions

View File

@ -66,6 +66,7 @@
#include "commands/typecmds.h"
#include "commands/user.h"
#include "commands/vacuum.h"
#include "common/int.h"
#include "executor/executor.h"
#include "foreign/fdwapi.h"
#include "foreign/foreign.h"
@ -3044,8 +3045,8 @@ MergeCheckConstraint(List *constraints, const char *name, Node *expr)
if (equal(expr, ccon->expr))
{
/* OK to merge constraint with existing */
ccon->inhcount++;
if (ccon->inhcount < 0)
if (pg_add_s16_overflow(ccon->inhcount, 1,
&ccon->inhcount))
ereport(ERROR,
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many inheritance parents"));
@ -3347,8 +3348,8 @@ MergeInheritedAttribute(List *inh_columns,
* Default and other constraints are handled by the caller.
*/
prevdef->inhcount++;
if (prevdef->inhcount < 0)
if (pg_add_s16_overflow(prevdef->inhcount, 1,
&prevdef->inhcount))
ereport(ERROR,
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many inheritance parents"));
@ -7089,8 +7090,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
get_collation_name(childatt->attcollation))));
/* Bump the existing child att's inhcount */
childatt->attinhcount++;
if (childatt->attinhcount < 0)
if (pg_add_s16_overflow(childatt->attinhcount, 1,
&childatt->attinhcount))
ereport(ERROR,
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many inheritance parents"));
@ -10170,7 +10171,7 @@ addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, Relation rel,
Oid constrOid;
char *conname;
bool conislocal;
int coninhcount;
int16 coninhcount;
bool connoinherit;
Oid deleteTriggerOid,
updateTriggerOid;
@ -10549,9 +10550,9 @@ addFkRecurseReferencing(List **wqueue, Constraint *fkconstraint, Relation rel,
NULL,
NULL,
NULL,
false,
1,
false,
false, /* conIsLocal */
1, /* conInhCount */
false, /* conNoInherit */
with_period, /* conPeriod */
false);
@ -11076,8 +11077,8 @@ CloneFkReferencing(List **wqueue, Relation parentRel, Relation partRel)
NULL,
NULL,
NULL,
false, /* islocal */
1, /* inhcount */
false, /* conIsLocal */
1, /* conInhCount */
false, /* conNoInherit */
with_period, /* conPeriod */
true);
@ -15944,8 +15945,8 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel, bool ispart
* OK, bump the child column's inheritance count. (If we fail
* later on, this change will just roll back.)
*/
child_att->attinhcount++;
if (child_att->attinhcount < 0)
if (pg_add_s16_overflow(child_att->attinhcount, 1,
&child_att->attinhcount))
ereport(ERROR,
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many inheritance parents"));
@ -16075,8 +16076,9 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel)
*/
child_copy = heap_copytuple(child_tuple);
child_con = (Form_pg_constraint) GETSTRUCT(child_copy);
child_con->coninhcount++;
if (child_con->coninhcount < 0)
if (pg_add_s16_overflow(child_con->coninhcount, 1,
&child_con->coninhcount))
ereport(ERROR,
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many inheritance parents"));