]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
IMPORT: ebtree: Fix UB from clz(0)
authorBen Kallus <benjamin.p.kallus.gr@dartmouth.edu>
Sat, 13 Sep 2025 12:00:03 +0000 (14:00 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 17 Sep 2025 12:30:32 +0000 (14:30 +0200)
From 'man gcc': passing 0 as the argument to "__builtin_ctz" or
"__builtin_clz" invokes undefined behavior. This triggers UBsan
in HAProxy.

[wt: tested in treebench and verified not to cause any performance
 regression with opstime-u32 nor stress-u32]
Signed-off-by: Willy Tarreau <w@1wt.eu>
This is ebtree commit 8c29daf9fa6e34de8c7684bb7713e93dcfe09029.
Signed-off-by: Willy Tarreau <w@1wt.eu>
This is ebtree commit cf3b93736cb550038325e1d99861358d65f70e9a.

include/import/eb32tree.h

index 9b331f609312c27a99db8e2e2c63184faa167952..54fb522608233bc742e2677e433467807a70afaf 100644 (file)
@@ -309,9 +309,6 @@ __eb32_insert(struct eb_root *root, struct eb32_node *new) {
         * would sit on different branches).
         */
 
-       // note that if EB_NODE_BITS > 1, we should check that it's still >= 0
-       new->node.bit = flsnz(new->key ^ old->key) - EB_NODE_BITS;
-
        if (new->key == old->key) {
                new->node.bit = -1; /* mark as new dup tree, just in case */
 
@@ -330,6 +327,10 @@ __eb32_insert(struct eb_root *root, struct eb32_node *new) {
                }
                /* otherwise fall through */
        }
+       else {
+               /* note that if EB_NODE_BITS > 1, we should check that it's still >= 0 */
+               new->node.bit = flsnz(new->key ^ old->key) - EB_NODE_BITS;
+       }
 
        if (new->key >= old->key) {
                new->node.branches.b[EB_LEFT] = troot;
@@ -446,9 +447,6 @@ __eb32i_insert(struct eb_root *root, struct eb32_node *new) {
         * would sit on different branches).
         */
 
-       // note that if EB_NODE_BITS > 1, we should check that it's still >= 0
-       new->node.bit = flsnz(new->key ^ old->key) - EB_NODE_BITS;
-
        if (new->key == old->key) {
                new->node.bit = -1; /* mark as new dup tree, just in case */
 
@@ -467,6 +465,10 @@ __eb32i_insert(struct eb_root *root, struct eb32_node *new) {
                }
                /* otherwise fall through */
        }
+       else {
+               /* note that if EB_NODE_BITS > 1, we should check that it's still >= 0 */
+               new->node.bit = flsnz(new->key ^ old->key) - EB_NODE_BITS;
+       }
 
        if ((s32)new->key >= (s32)old->key) {
                new->node.branches.b[EB_LEFT] = troot;