Skip to content

pgcolumnar.truncate() takes its lock and names the relation type before checking ownership (the #749 pattern) #1384

Closed

Description

@jdatcmd

Found while reviewing #1381.

What happens

pgcolumnar_truncate (src/columnar_vacuum.c, around line 2917 on main 9b3c181) does three things in this order:

  1. table_open(relid, ShareUpdateExclusiveLock);
  2. refuses a non-columnar relation with "relation … is not a columnar table";
  3. PgColumnarRequireTableOwner(rel).

This is the order #749 fixed in the five maintenance entry points. It has two consequences:

  • A non-owner queues for the lock. If the owner holds a conflicting lock, the non-owner waits behind it, and so does every later request.
  • A non-owner learns the relation type of a table they have no rights on.

Reproduced (by the #1381 review): a probe in a copy of vacuum_lock_privilege.sh gave
FAIL REVIEW PROBE truncate refuses a non-owner before its lock: got [locktimeout] want [owner]

None of the privilege suites covers truncate.

Proposed fix

Do what #749 did:

  • check ownership by OID (PgColumnarRequireTableOwnerByOid(relid)) before table_open;
  • then check the type.

The arms, red first, in vacuum_lock_privilege (both twins):

  • "truncate refuses a non-owner before taking its lock", under the existing contention holder;
  • "truncate tells a non-owner nothing about the relation type", as notowner_heap does for compact.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions