mirror of https://github.com/openssl/openssl.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 <tjh@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/20782)
This commit is contained in:
parent
4df13d1054
commit
eb0935fd21
|
@ -315,39 +315,54 @@ void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int internal_find(OPENSSL_STACK *st, const void *data,
|
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;
|
const void *r;
|
||||||
int i;
|
int i, count = 0;
|
||||||
|
int *pnum = pnum_matched;
|
||||||
|
|
||||||
if (st == NULL || st->num == 0)
|
if (st == NULL || st->num == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (pnum == NULL)
|
||||||
|
pnum = &count;
|
||||||
|
|
||||||
if (st->comp == NULL) {
|
if (st->comp == NULL) {
|
||||||
for (i = 0; i < st->num; i++)
|
for (i = 0; i < st->num; i++)
|
||||||
if (st->data[i] == data) {
|
if (st->data[i] == data) {
|
||||||
if (pnum != NULL)
|
*pnum = 1;
|
||||||
*pnum = 1;
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
if (pnum != NULL)
|
*pnum = 0;
|
||||||
*pnum = 0;
|
|
||||||
return -1;
|
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)
|
if (data == NULL)
|
||||||
return -1;
|
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;
|
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,
|
||||||
ret_val_options);
|
ret_val_options);
|
||||||
|
|
||||||
if (pnum != NULL) {
|
if (pnum_matched != NULL) {
|
||||||
*pnum = 0;
|
*pnum = 0;
|
||||||
if (r != NULL) {
|
if (r != NULL) {
|
||||||
const void **p = (const void **)r;
|
const void **p = (const void **)r;
|
||||||
|
|
Loading…
Reference in New Issue