From ddbff4e2358a89c67bd10ad3dd6cef88cf78f368 Mon Sep 17 00:00:00 2001 From: Ben Kallus Date: Sat, 13 Sep 2025 14:00:03 +0200 Subject: [PATCH] IMPORT: ebtree: Fix UB from clz(0) 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 This is ebtree commit 8c29daf9fa6e34de8c7684bb7713e93dcfe09029. Signed-off-by: Willy Tarreau This is ebtree commit cf3b93736cb550038325e1d99861358d65f70e9a. --- include/import/eb32tree.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/include/import/eb32tree.h b/include/import/eb32tree.h index 9b331f609..54fb52260 100644 --- a/include/import/eb32tree.h +++ b/include/import/eb32tree.h @@ -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;