]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
add cmp_thunk function to ossl_bsearch
authorNeil Horman <nhorman@openssl.org>
Tue, 13 Jan 2026 21:25:21 +0000 (16:25 -0500)
committerNeil Horman <nhorman@openssl.org>
Sat, 7 Feb 2026 18:11:02 +0000 (13:11 -0500)
Add the initial groundwork to allow for the use of a thunking function
with bsearch.  Normally our comparison function signature doesn't match
the type of the pointer we call it through, leading to ubsan errors,
this lets those signatures match and gives us a place to do the proper
casting

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Sat Feb  7 18:11:11 2026
(Merged from https://github.com/openssl/openssl/pull/29640)

crypto/bsearch.c
crypto/objects/obj_dat.c
crypto/property/property_query.c
crypto/stack/stack.c
include/internal/cryptlib.h

index 192ccbeb916f5e5618ed37f548386af8b11996b4..dcc3201baa875431d033d0a47acd35b617010e99 100644 (file)
 #include <stddef.h>
 #include "internal/cryptlib.h"
 
+typedef int (*cmpthunk_fn)(const void *, const void *);
 const void *ossl_bsearch(const void *key, const void *base, int num,
     int size, int (*cmp)(const void *, const void *),
+    int (*cmp_thunk)(cmpthunk_fn real_cmp_fn, const void *, const void *),
     int flags)
 {
     const char *base_ = base;
@@ -25,7 +27,10 @@ const void *ossl_bsearch(const void *key, const void *base, int num,
     while (l < h) {
         i = (l + h) / 2;
         p = &(base_[i * size]);
-        c = (*cmp)(key, p);
+        if (cmp_thunk != NULL)
+            c = cmp_thunk((cmpthunk_fn)cmp, key, (const void *)p);
+        else
+            c = cmp(key, p);
         if (c < 0)
             h = i;
         else if (c > 0)
@@ -36,8 +41,16 @@ const void *ossl_bsearch(const void *key, const void *base, int num,
     if (c != 0 && !(flags & OSSL_BSEARCH_VALUE_ON_NOMATCH))
         p = NULL;
     else if (c == 0 && (flags & OSSL_BSEARCH_FIRST_VALUE_ON_MATCH)) {
-        while (i > 0 && (*cmp)(key, &(base_[(i - 1) * size])) == 0)
+        while (i > 0) {
+            if (cmp_thunk != NULL) {
+                if (cmp_thunk((cmpthunk_fn)cmp, key, (const void *)&(base_[(i - 1) * size])))
+                    break;
+            } else {
+                if (cmp(key, &(base_[(i - 1) * size])))
+                    break;
+            }
             i--;
+        }
         p = &(base_[i * size]);
     }
     return p;
index ac95d098b9c8aaeea68cfced6aae8e9642f9a30f..835e1affae62f30a73b82adf7c3bde8a15a43c56 100644 (file)
@@ -618,7 +618,7 @@ const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
     int (*cmp)(const void *, const void *),
     int flags)
 {
-    const char *p = ossl_bsearch(key, base, num, size, cmp, flags);
+    const char *p = ossl_bsearch(key, base, num, size, cmp, NULL, flags);
 
 #ifdef CHARSET_EBCDIC
     /*
index f5daca2aad17cf1a4f5f6fb95e755ef3376ddc3c..e4935b66d29ad0ee8707b17d7eda1fcc1ac77c22 100644 (file)
@@ -30,7 +30,7 @@ ossl_property_find_property(const OSSL_PROPERTY_LIST *list,
         return NULL;
 
     return ossl_bsearch(&name_idx, list->properties, list->num_properties,
-        sizeof(*list->properties), &property_idx_cmp, 0);
+        sizeof(*list->properties), &property_idx_cmp, NULL, 0);
 }
 
 OSSL_PROPERTY_TYPE ossl_property_get_type(const OSSL_PROPERTY_DEFINITION *prop)
index d35348743bfdbfb671073a15b2b7a0273d939403..17962393356c7e04dffa1ad0315939f4f3f54c17 100644 (file)
@@ -359,7 +359,7 @@ static int internal_find(const OPENSSL_STACK *st, const void *data,
 
     if (pnum_matched != NULL)
         ret_val_options |= OSSL_BSEARCH_FIRST_VALUE_ON_MATCH;
-    r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp,
+    r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp, NULL,
         ret_val_options);
 
     if (pnum_matched != NULL) {
index 625d9d12ef208fe042340c05a641093ed3a539c3..d8a745ad189ad8b6599c59807d3b975c456f1ad1 100644 (file)
@@ -151,6 +151,7 @@ int ossl_crypto_free_ex_index_ex(OSSL_LIB_CTX *ctx, int class_index, int idx);
 
 const void *ossl_bsearch(const void *key, const void *base, int num,
     int size, int (*cmp)(const void *, const void *),
+    int (*cmp_thunk)(int (*real_cmp_fn)(const void *, const void *), const void *, const void *),
     int flags);
 
 char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text,