Fix off-by-one in LimitAdditionalPins()
authorAndres Freund <[email protected]>
Tue, 25 Jul 2023 02:07:52 +0000 (19:07 -0700)
committerAndres Freund <[email protected]>
Tue, 25 Jul 2023 02:11:51 +0000 (19:11 -0700)
Due to the bug LimitAdditionalPins() could return 0, violating
LimitAdditionalPins()'s API ("One additional pin is always allowed"). This
could be hit when setting shared_buffers very low and using a fair amount of
concurrency.

This bug was introduced in 31966b151e6a.

Author: "Anton A. Melnikov" <[email protected]>
Reported-by: "Anton A. Melnikov" <[email protected]>
Reported-by: Victoria Shepard
Discussion: https://postgr.es/m/ae46f2fb-5586-3de0-b54b-1bb0f6410ebd@inbox.ru
Backpatch: 16-

src/backend/storage/buffer/bufmgr.c

index 3c59bbd04ea702cbe62fa0bbb892fbbd18cc5937..bd203c21913778e4077b5ebd18f7b9f79eed3279 100644 (file)
@@ -1767,7 +1767,7 @@ LimitAdditionalPins(uint32 *additional_pins)
     */
    max_proportional_pins -= PrivateRefCountOverflowed + REFCOUNT_ARRAY_ENTRIES;
 
-   if (max_proportional_pins < 0)
+   if (max_proportional_pins <= 0)
        max_proportional_pins = 1;
 
    if (*additional_pins > max_proportional_pins)