Thread: Possible api miuse bms_next_member

Possible api miuse bms_next_member

From
Ranier Vilela
Date:
Hi.

Per Coverity.

CID 1608872: (#1 of 1): Improper use of negative value (NEGATIVE_RETURNS)
32. negative_returns: bms_next_member(child_joinrel->relids, -1) is passed to a parameter that cannot be negative.[show details] 

CID 1608871: (#1 of 1): Out-of-bounds access (OVERRUN)
32. overrun-buffer-arg: Calling add_child_eq_member with cur_ec->ec_childmembers and bms_next_member(child_joinrel->relids, -1) is suspicious because of the very large index, 4294967294. The index may be due to a negative parameter being interpreted as unsigned.


Coverity has two new reports about use of the function *bms_next_member*.
I think that he is right.

The function bms_next_member can return NEGATIVE.
So it is necessary to validate the function's return.

Attached has three patchs.

1. src/backend/optimizer/path/equivclass.c
Source of the Coverity report.

Function: add_child_join_rel_equivalences
Check the return of bms_next_member and avoid
continue if return is negative.

2. src/backend/partitioning/partprune.c
Function: make_partition_pruneinfo
Check the return of bms_next_member and avoid look if
targetpart if not found.

3. contrib/postgres_fdw/postgres_fdw.c
Function: postgresBeginForeignScan
Check the return of bms_next_member and abort if fail.

Function: postgresExplainForeignScan
Check the return of bms_next_member and abort if fail.

The patchs are attempts, not definitive fixes.

best regards,
Ranier Vilela
Attachment

Re: Possible api miuse bms_next_member

From
Matthias van de Meent
Date:
On Wed, 9 Apr 2025 at 15:01, Ranier Vilela <ranier.vf@gmail.com> wrote:
>
> Hi.
>
> Per Coverity.
>
> CID 1608872: (#1 of 1): Improper use of negative value (NEGATIVE_RETURNS)
> 32. negative_returns: bms_next_member(child_joinrel->relids, -1) is passed to a parameter that cannot be
negative.[showdetails] 
>
> CID 1608871: (#1 of 1): Out-of-bounds access (OVERRUN)
> 32. overrun-buffer-arg: Calling add_child_eq_member with cur_ec->ec_childmembers and
bms_next_member(child_joinrel->relids,-1) is suspicious because of the very large index, 4294967294. The index may be
dueto a negative parameter being interpreted as unsigned. 
>
> Coverity has two new reports about use of the function *bms_next_member*.
> I think that he is right.
>
> The function bms_next_member can return NEGATIVE.
> So it is necessary to validate the function's return.

I don't know much about the planner, but I would expect a RelOptInfo's
relids field to always contain at least one relid when it's not
currently being constructed; thus guaranteeing a non-negative result
when looking for the first bit (as indicated by "next bit after -1").

Or did I miss something?

Kind regards,

Matthias van de Meent
Neon (https://neon.tech)



Re: Possible api miuse bms_next_member

From
Ranier Vilela
Date:
Em qua., 9 de abr. de 2025 às 10:27, Matthias van de Meent <boekewurm+postgres@gmail.com> escreveu:
On Wed, 9 Apr 2025 at 15:01, Ranier Vilela <ranier.vf@gmail.com> wrote:
>
> Hi.
>
> Per Coverity.
>
> CID 1608872: (#1 of 1): Improper use of negative value (NEGATIVE_RETURNS)
> 32. negative_returns: bms_next_member(child_joinrel->relids, -1) is passed to a parameter that cannot be negative.[show details]
>
> CID 1608871: (#1 of 1): Out-of-bounds access (OVERRUN)
> 32. overrun-buffer-arg: Calling add_child_eq_member with cur_ec->ec_childmembers and bms_next_member(child_joinrel->relids, -1) is suspicious because of the very large index, 4294967294. The index may be due to a negative parameter being interpreted as unsigned.
>
> Coverity has two new reports about use of the function *bms_next_member*.
> I think that he is right.
>
> The function bms_next_member can return NEGATIVE.
> So it is necessary to validate the function's return.

I don't know much about the planner, but I would expect a RelOptInfo's
relids field to always contain at least one relid when it's not
currently being constructed; thus guaranteeing a non-negative result
when looking for the first bit (as indicated by "next bit after -1").
I think it is worth the effort to prevent this.
In this particular case, the function *add_child_join_rel_equivalences*,
has the following comment:
"Note that this function won't be called at all unless we have at least some
 * reason to believe that the EC members it generates will be useful."
So I believe the function is not critical.

best regards,
Ranier Vilela

Re: Possible api miuse bms_next_member

From
Tom Lane
Date:
Matthias van de Meent <boekewurm+postgres@gmail.com> writes:
> On Wed, 9 Apr 2025 at 15:01, Ranier Vilela <ranier.vf@gmail.com> wrote:
>> Coverity has two new reports about use of the function *bms_next_member*.
>> I think that he is right.

> I don't know much about the planner, but I would expect a RelOptInfo's
> relids field to always contain at least one relid when it's not
> currently being constructed; thus guaranteeing a non-negative result
> when looking for the first bit (as indicated by "next bit after -1").

Indeed.  These patches are all useless IMO.  I'm not sure that this
is really a great way to select a representative member of the
child-relids set, but it won't fail, and if it did we'd have way
worse problems.  (For starters: if a child rel's relids set is
empty, then presumably so was the parent's, meaning we cannot
tell them apart.)

If we did want to do something about this warning, rather than
hacking up the call sites I'd be inclined to invent something like
"bms_first_member()" which does the same thing but additionally
asserts on empty input.  Not really convinced it's worth the
trouble though.

            regards, tom lane



Re: Possible api miuse bms_next_member

From
David Rowley
Date:
On Thu, 10 Apr 2025 at 02:18, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> If we did want to do something about this warning, rather than
> hacking up the call sites I'd be inclined to invent something like
> "bms_first_member()" which does the same thing but additionally
> asserts on empty input.  Not really convinced it's worth the
> trouble though.

Aha, a reincarnation! (462bb7f12).

My vote too is to do nothing.

David