Re: glibc qsort() vulnerability - Mailing list pgsql-hackers

From Mats Kindahl
Subject Re: glibc qsort() vulnerability
Date
Msg-id CA+14427QfHELBNskJKPHA96yOJ6aUZE_XqbFBC7hz+hmywTtPQ@mail.gmail.com
Whole thread Raw
In response to Re: glibc qsort() vulnerability  (Mats Kindahl <mats@timescale.com>)
Responses Re: glibc qsort() vulnerability
List pgsql-hackers
On Fri, Feb 9, 2024 at 8:26 PM Mats Kindahl <mats@timescale.com> wrote:
On Fri, Feb 9, 2024 at 5:24 PM Nathan Bossart <nathandbossart@gmail.com> wrote:
On Fri, Feb 09, 2024 at 08:52:26AM +0100, Mats Kindahl wrote:
> Here is a new version introducing pg_cmp_s32 and friends and use them
> instead of the INT_CMP macro introduced before. It also moves the
> definitions to common/int.h and adds that as an include to all locations
> using these functions.

Thanks for the new version of the patch.

> Note that for integers with sizes less than sizeof(int), C standard
> conversions will convert the values to "int" before doing the arithmetic,
> so no casting is *necessary*. I did not force the 16-bit functions to
> return -1 or 1 and have updated the comment accordingly.

It might not be necessary, but this is one of those places where I would
add casting anyway to make it abundantly clear what we are expecting to
happen and why it is safe.

I'll add it.
 
> The types "int" and "size_t" are treated as s32 and u32 respectively since
> that seems to be the case for most of the code, even if strictly not
> correct (size_t can be an unsigned long int for some architecture).

Why is it safe to do this?

> -     return ((const SPLITCOST *) a)->cost - ((const SPLITCOST *) b)->cost;
> +     return INT_CMP(((const SPLITCOST *) a)->cost, ((const SPLITCOST *) b)->cost);

The patch still contains several calls to INT_CMP.

I'll fix it.
 

> +/*------------------------------------------------------------------------
> + * Comparison routines for integers
> + *------------------------------------------------------------------------
> + */

I'd suggest separating this part out to a 0001 patch to make it easier to
review.  The 0002 patch could take care of converting the existing qsort
comparators.

Ok. Will split it out into two patches.
 

> +static inline int
> +pg_cmp_s16(int16 a, int16 b)
> +{
> +     return a - b;
> +}
> +
> +static inline int
> +pg_cmp_u16(uint16 a, uint16 b)
> +{
> +     return a - b;
> +}
> +
> +static inline int
> +pg_cmp_s32(int32 a, int32 b)
> +{
> +     return (a > b) - (a < b);
> +}
> +
> +static inline int
> +pg_cmp_u32(uint32 a, uint32 b)
> +{
> +     return (a > b) - (a < b);
> +}
> +
> +static inline int
> +pg_cmp_s64(int64 a, int64 b)
> +{
> +     return (a > b) - (a < b);
> +}
> +
> +static inline int
> +pg_cmp_u64(uint64 a, uint64 b)
> +{
> +     return (a > b) - (a < b);
> +}

As suggested above, IMHO we should be rather liberal with the casting to
ensure it is abundantly clear what is happening here.

Ok.

QQ: right now it looks like this:

static inline int
pg_cmp_u16(uint16 a, uint16 b)
{
return (int32)a - (int32)b;
}

and

static inline int
pg_cmp_u32(uint32 a, uint32 b)
{
return (a > b) - (a < b);
}

I think that is clear enough, but do you want more casts added for the return value as well?

Best wishes,
Mats Kindahl
 
 

--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com

pgsql-hackers by date:

Previous
From: Mats Kindahl
Date:
Subject: Re: glibc qsort() vulnerability
Next
From: Andres Freund
Date:
Subject: Re: Simplify documentation related to Windows builds