[PATCH v1] Reject zero resource kinds in test_resowner_many()

Started by Grigorev Jurij9 days ago1 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253764
psql -h localhost -U postgres

Built from patchset v1 (message #1), September 20, 2026 at 10:04 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t253764_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253764_1 && git checkout t253764_1

Patchset v1 (message #1) is on t253764_1

Jump to latest
#1Grigorev Jurij
ju.grigorev@ftdata.ru

Hi hackers,

While running Clang Static Analyzer through CodeChecker over PostgreSQL
18.6, we found a possible division by zero in
RememberManyTestResources():

kind_idx = (kind_idx + 1) % nkinds;

The SQL entry point rejects negative values of nkinds but accepts zero.
If there are resources to remember, the helper then accesses kinds[0]
even though the array contains no resource kinds, and can eventually
reach the modulo operation.

For example:

CREATE EXTENSION test_resowner;
SELECT test_resowner_many(0, 1, 0, 0, 0);

On an assertion-enabled master build on macOS, I get:

NOTICE: remembering 1 before-locks resources
TRAP: failed Assert("kind->release_phase != 0"),
File: "../src/backend/utils/resowner/resowner.c", Line: 536
LOG: client backend was terminated by signal 6: Abort trap: 6

ResourceOwnerRemember() detects the invalid descriptor passed as
&kinds[0].desc, so this build fails before reaching the division.

The after-locks path has the same problem:

SELECT test_resowner_many(0, 0, 0, 1, 0);

Interestingly, in the same build this failed the neighboring assertion:

TRAP: failed Assert("kind->release_priority != 0"),
File: "../src/backend/utils/resowner/resowner.c", Line: 537

The two calls fail at different checks depending on the contents of the
invalid kinds[0] entry. Without assertions, the code has already
invoked undefined behavior before reaching the modulo, so the exact
failure mode is not predictable.

ForgetManyTestResources() contains another "% nkinds", but that
expression is inside a loop bounded by nkinds. With nkinds equal to
zero, the loop body is never entered, so only the remember path needs
fixing.

The patch rejects nkinds <= 0 at the SQL entry point, matching
test_resowner_priorities() in the same module. It also adds an
assertion documenting the helper's precondition and regression coverage
for both remember paths.

This deliberately changes the behavior of the all-zero invocation:

SELECT test_resowner_many(0, 0, 0, 0, 0);

It currently succeeds as a no-op, but with the patch it returns:

ERROR: nkinds must be greater than zero

I think rejecting it is preferable because zero resource kinds do not
have a useful meaning for this test. Would it be better to preserve
the all-zero no-op case and reject nkinds = 0 only when resources are
requested?

The issue was introduced with the test_resowner module in commit
b8bff07daa85, so PostgreSQL 17, PostgreSQL 18, and master are affected.
It is confined to the test module; production ResourceOwner code is not
affected.

The patch applies cleanly to current master. I reproduced both failures
without the patch and verified that the test_resowner regression test
passes with it applied.

I would also appreciate opinions on whether this test-only fix is worth
back-patching to PostgreSQL 17 and 18. I can prepare separate
back-branch patches if needed.

I will add the patch to the CommitFest.

Best regards,
Yuriy Grigoryev

Attachments:

t253764_1
v1-0001-Reject-zero-resource-kinds-in-test_resowner_many.patchapplication/octet-stream; name=v1-0001-Reject-zero-resource-kinds-in-test_resowner_many.patchDownload+13-3