From: Pauli Date: Thu, 20 Apr 2023 06:04:10 +0000 (+1000) Subject: stack: fix searching when the stack isn't sorted. X-Git-Tag: openssl-3.2.0-alpha1~953 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eb0935fd21220708e4321374380db497e9c5ecdf;p=thirdparty%2Fopenssl.git stack: fix searching when the stack isn't sorted. More specifically, don't sort the stack when searching when it isn't sorted. This avoids a race condition. Fixes #20135 Reviewed-by: Tim Hudson Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/20782) --- diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c index 601664ebe3d..1e7f3007230 100644 --- a/crypto/stack/stack.c +++ b/crypto/stack/stack.c @@ -315,39 +315,54 @@ void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc) } static int internal_find(OPENSSL_STACK *st, const void *data, - int ret_val_options, int *pnum) + int ret_val_options, int *pnum_matched) { const void *r; - int i; + int i, count = 0; + int *pnum = pnum_matched; if (st == NULL || st->num == 0) return -1; + if (pnum == NULL) + pnum = &count; + if (st->comp == NULL) { for (i = 0; i < st->num; i++) if (st->data[i] == data) { - if (pnum != NULL) - *pnum = 1; + *pnum = 1; return i; } - if (pnum != NULL) - *pnum = 0; + *pnum = 0; return -1; } - if (!st->sorted) { - if (st->num > 1) - qsort(st->data, st->num, sizeof(void *), st->comp); - st->sorted = 1; /* empty or single-element stack is considered sorted */ - } if (data == NULL) return -1; - if (pnum != NULL) + + if (!st->sorted) { + int res = -1; + + for (i = 0; i < st->num; i++) + if (st->comp(&data, st->data + i) == 0) { + if (res == -1) + res = i; + ++*pnum; + /* Check if only one result is wanted and exit if so */ + if (pnum_matched == NULL) + return i; + } + if (res == -1) + *pnum = 0; + return res; + } + + 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, ret_val_options); - if (pnum != NULL) { + if (pnum_matched != NULL) { *pnum = 0; if (r != NULL) { const void **p = (const void **)r;