Re: Fw:Re: Fw: ltree_compare in contrib/ltree/ltree_op.c overflows int32 on deep ltree comparisons, returning the wrong sign

From: Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>
To: 王跃林 <violin0613(at)tju(dot)edu(dot)cn>
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: Fw:Re: Fw: ltree_compare in contrib/ltree/ltree_op.c overflows int32 on deep ltree comparisons, returning the wrong sign
Date: 2026-06-13 06:12:44
Message-ID: CAJTYsWUurV6dBhnyd6R7W1w7Fy6FiG9-F_Swk_GDXQQpHoiciA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi,

On Sat, 13 Jun 2026 at 09:20, 王跃林 <violin0613(at)tju(dot)edu(dot)cn> wrote:

> 主题:Re: Fw: ltree_compare in contrib/ltree/ltree_op.c overflows int32 on deep ltree comparisons, returning the wrong sign
> On Mon, May 25, 2026 at 10:58:05PM +0800, violin0613(at)tju(dot)edu(dot)cn wrote:
> > PoC
> >
> > File vuln_001.sql
> >
> > CREATE EXTENSION IF NOT EXISTS ltree;
> > â
> > WITH s AS (SELECT 'a'::ltree AS v),
> > l AS (SELECT (repeat('a.', 19999) || 'a')::ltree AS v)
> > SELECT (l.v > s.v) AS long_gt_short_expected_true,
> > (l.v < s.v) AS long_lt_short_expected_false
> > FROM s, l;
> >
> > Process
> >
> > psql -h /tmp -p 36265 -U postgres -f vuln_001.sql
> >
> > Results
> >
> > long_gt_short_expected_true | long_lt_short_expected_false
> > -----------------------------+------------------------------
> > f | t
> >
> > Both columns are inverted. long > short returned false, long < short
> > returned true.
>
>
This looks like a classic case of integer overflow that's
happening in ltree_compare function in ltree_op.c.

return (al->len - bl->len) * 10 * (an + 1);
return res * 10 * (an + 1);
return (a->numlevel - b->numlevel) * 10 * (an + 1);

I think the calculation should be done as int64, something of this sort:

int64 v = (int64) (al->len - bl->len) * 10 * (an + 1);
if (v > PG_INT32_MAX) return PG_INT32_MAX;
if (v < PG_INT32_MIN) return PG_INT32_MIN;
return (int) v;

And needed to adjust the ltree_penalty function too.

Attached is a draft patch for this, I guess we can add a helper
function too for the above conversion.

Thoughts?

Regards,
Ayush

Attachment Content-Type Size
0001-Fix-int32-overflow-in-ltree_compare.patch application/octet-stream 5.2 KB

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message PG Bug reporting form 2026-06-14 07:00:01 BUG #19519: REPACK can fail due to missing chunk for toast value
Previous Message 王跃林 2026-06-13 03:50:25 Fw:Re: Fw: ltree_compare in contrib/ltree/ltree_op.c overflows int32 on deep ltree comparisons, returning the wrong sign