Bug 15569 - ldb qsort might r/w out of bounds with an intransitive compare function
Summary: ldb qsort might r/w out of bounds with an intransitive compare function
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: AD: LDB/DSDB/SAMDB (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Samba QA Contact
QA Contact: Samba QA Contact
URL: https://www.openwall.com/lists/oss-se...
Keywords:
Depends on:
Blocks:
 
Reported: 2024-02-04 23:44 UTC by Douglas Bagnall
Modified: 2024-04-10 23:59 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Douglas Bagnall 2024-02-04 23:44:59 UTC
On the oss-security mailing list, Qualys report that the quicksort implementation in glibc is liable to read and write out of bounds with an intransitive compare function function (which includes the `return a - b` type). 

https://www.openwall.com/lists/oss-security/2024/01/30/7

With glibc it is bit fiddly to force qsort into using quicksort -- it tries a mergesort first and only resorts to quicksort if an allocation fails[1] -- but in 2006 we adapted the glibc code for lib/ldb/common/qsort.c and that uses the quicksort unconditionally.

I haven't checked, but don't I imagine we have non-transitive compares (I think I tried to write one but Jo Sutton stopped me), so this might not be a real problem. Nevertheless, LDB is a semi-public library and there might be other vulnerable users.

The mergesort-first behaviour of glibc leads to other bugs we have, where we assume a stable qsort(), which is not common on non-GNU platforms. Indeed, the Qualys article mentions that GNU wanted to change their qsort() to a quicker unstable sort, but it broke too many applications that erroneously relied on the stable behaviour.

I think we forked qsort to get qsort_r behaviour for ldb. We now have lib/util/stablesort.c for reliable stable sorts. It includes a qsort_r type function, so we could use that for ldb_qsort().
Comment 1 Douglas Bagnall 2024-02-06 21:38:26 UTC
> We now have lib/util/stablesort.c for reliable stable sorts. It includes a qsort_r type function, so we could use that for ldb_qsort().

Which is not to say we shouldn't do the simple patch first, with involves adding a `tmp_ptr != base_ptr &&` in one place.


> I haven't checked, but don't I imagine we have non-transitive compares[...]

These ones look dodgy:

winsdb_addr_sort_list() in source4/nbt_server/wins/winsdb.c
nbtd_wins_randomize1Clist_sort() in source4/nbt_server/wins/winsserver.c

I am not completely sure about *all* the others, as some of the code is a bit complex and might introduce non-transitivity in other ways.

> Nevertheless, LDB is a semi-public library and there might be other vulnerable users.

I can find no use of ldb_qsort() in sssd, so probably that's fine.
Comment 2 Jo Sutton 2024-02-06 22:33:33 UTC
In case it’s useful, here’s my old patch to remove ldb_qsort(): https://gitlab.com/samba-team/devel/samba/-/commit/22ba148e2b763ce4644b6a28d9da0a36198026f5
Comment 3 Douglas Bagnall 2024-02-06 23:00:30 UTC
(In reply to Douglas Bagnall from comment #1)
> winsdb_addr_sort_list() in source4/nbt_server/wins/winsdb.c

This one is probably OK, because the subtracted items are boolean.

and  

> nbtd_wins_randomize1Clist_sort() in source4/nbt_server/wins/winsserver.c

here I think the numbers are <= 32, so we're not looking at overflows.

Also the nbt server is not often used.
Comment 4 Douglas Bagnall 2024-04-08 10:03:35 UTC
I think we actually found this earlier:

https://bugzilla.samba.org/show_bug.cgi?id=14138#c4
and commit defb23732515e3c638d0081f5e4043fbb35d303c

> dns_name_compare() had logic to put @ and the top record in the tree being
> enumerated first, but if a domain had both then this would break the
> older qsort() implementation in ldb_qsort() and cause a read of memory
> before the base pointer.
Comment 5 Douglas Bagnall 2024-04-10 03:56:17 UTC
(In reply to Douglas Bagnall from comment #4)

> I think we actually found this earlier:

also https://bugzilla.samba.org/show_bug.cgi?id=3959
Comment 6 Douglas Bagnall 2024-04-10 23:37:36 UTC
also https://bugzilla.samba.org/show_bug.cgi?id=11503!
Comment 7 Samba QA Contact 2024-04-10 23:59:06 UTC
This bug was referenced in samba master:

73e4f6026ad04b73074b413bd8c838ca48ffde7f