/src/openssl111/crypto/stack/stack.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  |  * | 
| 4 |  |  * Licensed under the OpenSSL license (the "License").  You may not use | 
| 5 |  |  * this file except in compliance with the License.  You can obtain a copy | 
| 6 |  |  * in the file LICENSE in the source distribution or at | 
| 7 |  |  * https://www.openssl.org/source/license.html | 
| 8 |  |  */ | 
| 9 |  |  | 
| 10 |  | #include <stdio.h> | 
| 11 |  | #include "internal/cryptlib.h" | 
| 12 |  | #include "internal/numbers.h" | 
| 13 |  | #include <openssl/stack.h> | 
| 14 |  | #include <openssl/objects.h> | 
| 15 |  | #include <errno.h> | 
| 16 |  | #include <openssl/e_os2.h>      /* For ossl_inline */ | 
| 17 |  |  | 
| 18 |  | /* | 
| 19 |  |  * The initial number of nodes in the array. | 
| 20 |  |  */ | 
| 21 |  | static const int min_nodes = 4; | 
| 22 |  | static const int max_nodes = SIZE_MAX / sizeof(void *) < INT_MAX | 
| 23 |  |                              ? (int)(SIZE_MAX / sizeof(void *)) | 
| 24 |  |                              : INT_MAX; | 
| 25 |  |  | 
| 26 |  | struct stack_st { | 
| 27 |  |     int num; | 
| 28 |  |     const void **data; | 
| 29 |  |     int sorted; | 
| 30 |  |     int num_alloc; | 
| 31 |  |     OPENSSL_sk_compfunc comp; | 
| 32 |  | }; | 
| 33 |  |  | 
| 34 |  | OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc c) | 
| 35 | 86.8k | { | 
| 36 | 86.8k |     OPENSSL_sk_compfunc old = sk->comp; | 
| 37 |  |  | 
| 38 | 86.8k |     if (sk->comp != c) | 
| 39 | 86.8k |         sk->sorted = 0; | 
| 40 | 86.8k |     sk->comp = c; | 
| 41 |  |  | 
| 42 | 86.8k |     return old; | 
| 43 | 86.8k | } | 
| 44 |  |  | 
| 45 |  | OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk) | 
| 46 | 45.3k | { | 
| 47 | 45.3k |     OPENSSL_STACK *ret; | 
| 48 |  |  | 
| 49 | 45.3k |     if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { | 
| 50 | 0 |         CRYPTOerr(CRYPTO_F_OPENSSL_SK_DUP, ERR_R_MALLOC_FAILURE); | 
| 51 | 0 |         return NULL; | 
| 52 | 0 |     } | 
| 53 |  |  | 
| 54 |  |     /* direct structure assignment */ | 
| 55 | 45.3k |     *ret = *sk; | 
| 56 |  |  | 
| 57 | 45.3k |     if (sk->num == 0) { | 
| 58 |  |         /* postpone |ret->data| allocation */ | 
| 59 | 0 |         ret->data = NULL; | 
| 60 | 0 |         ret->num_alloc = 0; | 
| 61 | 0 |         return ret; | 
| 62 | 0 |     } | 
| 63 |  |     /* duplicate |sk->data| content */ | 
| 64 | 45.3k |     if ((ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc)) == NULL) | 
| 65 | 0 |         goto err; | 
| 66 | 45.3k |     memcpy(ret->data, sk->data, sizeof(void *) * sk->num); | 
| 67 | 45.3k |     return ret; | 
| 68 | 0 |  err: | 
| 69 | 0 |     OPENSSL_sk_free(ret); | 
| 70 | 0 |     return NULL; | 
| 71 | 45.3k | } | 
| 72 |  |  | 
| 73 |  | OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, | 
| 74 |  |                              OPENSSL_sk_copyfunc copy_func, | 
| 75 |  |                              OPENSSL_sk_freefunc free_func) | 
| 76 |  | { | 
| 77 |  |     OPENSSL_STACK *ret; | 
| 78 |  |     int i; | 
| 79 |  |  | 
| 80 |  |     if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { | 
| 81 |  |         CRYPTOerr(CRYPTO_F_OPENSSL_SK_DEEP_COPY, ERR_R_MALLOC_FAILURE); | 
| 82 |  |         return NULL; | 
| 83 |  |     } | 
| 84 |  |  | 
| 85 |  |     /* direct structure assignment */ | 
| 86 |  |     *ret = *sk; | 
| 87 |  |  | 
| 88 |  |     if (sk->num == 0) { | 
| 89 |  |         /* postpone |ret| data allocation */ | 
| 90 |  |         ret->data = NULL; | 
| 91 |  |         ret->num_alloc = 0; | 
| 92 |  |         return ret; | 
| 93 |  |     } | 
| 94 |  |  | 
| 95 |  |     ret->num_alloc = sk->num > min_nodes ? sk->num : min_nodes; | 
| 96 |  |     ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc); | 
| 97 |  |     if (ret->data == NULL) { | 
| 98 |  |         OPENSSL_free(ret); | 
| 99 |  |         return NULL; | 
| 100 |  |     } | 
| 101 |  |  | 
| 102 |  |     for (i = 0; i < ret->num; ++i) { | 
| 103 |  |         if (sk->data[i] == NULL) | 
| 104 |  |             continue; | 
| 105 |  |         if ((ret->data[i] = copy_func(sk->data[i])) == NULL) { | 
| 106 |  |             while (--i >= 0) | 
| 107 |  |                 if (ret->data[i] != NULL) | 
| 108 |  |                     free_func((void *)ret->data[i]); | 
| 109 |  |             OPENSSL_sk_free(ret); | 
| 110 |  |             return NULL; | 
| 111 |  |         } | 
| 112 |  |     } | 
| 113 |  |     return ret; | 
| 114 |  | } | 
| 115 |  |  | 
| 116 |  | OPENSSL_STACK *OPENSSL_sk_new_null(void) | 
| 117 | 66.9M | { | 
| 118 | 66.9M |     return OPENSSL_sk_new_reserve(NULL, 0); | 
| 119 | 66.9M | } | 
| 120 |  |  | 
| 121 |  | OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c) | 
| 122 | 4.05M | { | 
| 123 | 4.05M |     return OPENSSL_sk_new_reserve(c, 0); | 
| 124 | 4.05M | } | 
| 125 |  |  | 
| 126 |  | /* | 
| 127 |  |  * Calculate the array growth based on the target size. | 
| 128 |  |  * | 
| 129 |  |  * The growth fraction is a rational number and is defined by a numerator | 
| 130 |  |  * and a denominator.  According to Andrew Koenig in his paper "Why Are | 
| 131 |  |  * Vectors Efficient?" from JOOP 11(5) 1998, this factor should be less | 
| 132 |  |  * than the golden ratio (1.618...). | 
| 133 |  |  * | 
| 134 |  |  * We use 3/2 = 1.5 for simplicity of calculation and overflow checking. | 
| 135 |  |  * Another option 8/5 = 1.6 allows for slightly faster growth, although safe | 
| 136 |  |  * computation is more difficult. | 
| 137 |  |  * | 
| 138 |  |  * The limit to avoid overflow is spot on.  The modulo three correction term | 
| 139 |  |  * ensures that the limit is the largest number than can be expanded by the | 
| 140 |  |  * growth factor without exceeding the hard limit. | 
| 141 |  |  * | 
| 142 |  |  * Do not call it with |current| lower than 2, or it will infinitely loop. | 
| 143 |  |  */ | 
| 144 |  | static ossl_inline int compute_growth(int target, int current) | 
| 145 | 4.65M | { | 
| 146 | 4.65M |     const int limit = (max_nodes / 3) * 2 + (max_nodes % 3 ? 1 : 0); | 
| 147 |  |  | 
| 148 | 9.31M |     while (current < target) { | 
| 149 |  |         /* Check to see if we're at the hard limit */ | 
| 150 | 4.65M |         if (current >= max_nodes) | 
| 151 | 0 |             return 0; | 
| 152 |  |  | 
| 153 |  |         /* Expand the size by a factor of 3/2 if it is within range */ | 
| 154 | 4.65M |         current = current < limit ? current + current / 2 : max_nodes; | 
| 155 | 4.65M |     } | 
| 156 | 4.65M |     return current; | 
| 157 | 4.65M | } | 
| 158 |  |  | 
| 159 |  | /* internal STACK storage allocation */ | 
| 160 |  | static int sk_reserve(OPENSSL_STACK *st, int n, int exact) | 
| 161 | 141M | { | 
| 162 | 141M |     const void **tmpdata; | 
| 163 | 141M |     int num_alloc; | 
| 164 |  |  | 
| 165 |  |     /* Check to see the reservation isn't exceeding the hard limit */ | 
| 166 | 141M |     if (n > max_nodes - st->num) | 
| 167 | 0 |         return 0; | 
| 168 |  |  | 
| 169 |  |     /* Figure out the new size */ | 
| 170 | 141M |     num_alloc = st->num + n; | 
| 171 | 141M |     if (num_alloc < min_nodes) | 
| 172 | 9.96M |         num_alloc = min_nodes; | 
| 173 |  |  | 
| 174 |  |     /* If |st->data| allocation was postponed */ | 
| 175 | 141M |     if (st->data == NULL) { | 
| 176 |  |         /* | 
| 177 |  |          * At this point, |st->num_alloc| and |st->num| are 0; | 
| 178 |  |          * so |num_alloc| value is |n| or |min_nodes| if greater than |n|. | 
| 179 |  |          */ | 
| 180 | 6.44M |         if ((st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc)) == NULL) { | 
| 181 | 0 |             CRYPTOerr(CRYPTO_F_SK_RESERVE, ERR_R_MALLOC_FAILURE); | 
| 182 | 0 |             return 0; | 
| 183 | 0 |         } | 
| 184 | 6.44M |         st->num_alloc = num_alloc; | 
| 185 | 6.44M |         return 1; | 
| 186 | 6.44M |     } | 
| 187 |  |  | 
| 188 | 134M |     if (!exact) { | 
| 189 | 134M |         if (num_alloc <= st->num_alloc) | 
| 190 | 129M |             return 1; | 
| 191 | 5.25M |         num_alloc = compute_growth(num_alloc, st->num_alloc); | 
| 192 | 5.25M |         if (num_alloc == 0) | 
| 193 | 0 |             return 0; | 
| 194 | 5.25M |     } else if (num_alloc == st->num_alloc) { | 
| 195 | 0 |         return 1; | 
| 196 | 0 |     } | 
| 197 |  |  | 
| 198 | 5.25M |     tmpdata = OPENSSL_realloc((void *)st->data, sizeof(void *) * num_alloc); | 
| 199 | 5.25M |     if (tmpdata == NULL) | 
| 200 | 0 |         return 0; | 
| 201 |  |  | 
| 202 | 5.25M |     st->data = tmpdata; | 
| 203 | 5.25M |     st->num_alloc = num_alloc; | 
| 204 | 5.25M |     return 1; | 
| 205 | 5.25M | } | 
| 206 |  |  | 
| 207 |  | OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n) | 
| 208 | 71.0M | { | 
| 209 | 71.0M |     OPENSSL_STACK *st = OPENSSL_zalloc(sizeof(OPENSSL_STACK)); | 
| 210 |  |  | 
| 211 | 71.0M |     if (st == NULL) | 
| 212 | 0 |         return NULL; | 
| 213 |  |  | 
| 214 | 71.0M |     st->comp = c; | 
| 215 |  |  | 
| 216 | 71.0M |     if (n <= 0) | 
| 217 | 71.0M |         return st; | 
| 218 |  |  | 
| 219 | 115 |     if (!sk_reserve(st, n, 1)) { | 
| 220 | 0 |         OPENSSL_sk_free(st); | 
| 221 | 0 |         return NULL; | 
| 222 | 0 |     } | 
| 223 |  |  | 
| 224 | 115 |     return st; | 
| 225 | 115 | } | 
| 226 |  |  | 
| 227 |  | int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n) | 
| 228 | 0 | { | 
| 229 | 0 |     if (st == NULL) | 
| 230 | 0 |         return 0; | 
| 231 |  |  | 
| 232 | 0 |     if (n < 0) | 
| 233 | 0 |         return 1; | 
| 234 | 0 |     return sk_reserve(st, n, 1); | 
| 235 | 0 | } | 
| 236 |  |  | 
| 237 |  | int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc) | 
| 238 | 38.1M | { | 
| 239 | 38.1M |     if (st == NULL || st->num == max_nodes) | 
| 240 | 0 |         return 0; | 
| 241 |  |  | 
| 242 | 38.1M |     if (!sk_reserve(st, 1, 0)) | 
| 243 | 0 |         return 0; | 
| 244 |  |  | 
| 245 | 38.1M |     if ((loc >= st->num) || (loc < 0)) { | 
| 246 | 38.1M |         st->data[st->num] = data; | 
| 247 | 38.1M |     } else { | 
| 248 | 0 |         memmove(&st->data[loc + 1], &st->data[loc], | 
| 249 | 0 |                 sizeof(st->data[0]) * (st->num - loc)); | 
| 250 | 0 |         st->data[loc] = data; | 
| 251 | 0 |     } | 
| 252 | 38.1M |     st->num++; | 
| 253 | 38.1M |     st->sorted = 0; | 
| 254 | 38.1M |     return st->num; | 
| 255 | 38.1M | } | 
| 256 |  |  | 
| 257 |  | static ossl_inline void *internal_delete(OPENSSL_STACK *st, int loc) | 
| 258 | 446k | { | 
| 259 | 446k |     const void *ret = st->data[loc]; | 
| 260 |  |  | 
| 261 | 446k |     if (loc != st->num - 1) | 
| 262 | 22.7k |          memmove(&st->data[loc], &st->data[loc + 1], | 
| 263 | 22.7k |                  sizeof(st->data[0]) * (st->num - loc - 1)); | 
| 264 | 446k |     st->num--; | 
| 265 |  |  | 
| 266 | 446k |     return (void *)ret; | 
| 267 | 446k | } | 
| 268 |  |  | 
| 269 |  | void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p) | 
| 270 | 6.11k | { | 
| 271 | 6.11k |     int i; | 
| 272 |  |  | 
| 273 | 12.5k |     for (i = 0; i < st->num; i++) | 
| 274 | 12.5k |         if (st->data[i] == p) | 
| 275 | 6.11k |             return internal_delete(st, i); | 
| 276 | 0 |     return NULL; | 
| 277 | 6.11k | } | 
| 278 |  |  | 
| 279 |  | void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc) | 
| 280 | 84 | { | 
| 281 | 84 |     if (st == NULL || loc < 0 || loc >= st->num) | 
| 282 | 0 |         return NULL; | 
| 283 |  |  | 
| 284 | 84 |     return internal_delete(st, loc); | 
| 285 | 84 | } | 
| 286 |  |  | 
| 287 |  | static int internal_find(OPENSSL_STACK *st, const void *data, | 
| 288 |  |                          int ret_val_options) | 
| 289 | 21.9k | { | 
| 290 | 21.9k |     const void *r; | 
| 291 | 21.9k |     int i; | 
| 292 |  |  | 
| 293 | 21.9k |     if (st == NULL || st->num == 0) | 
| 294 | 11.4k |         return -1; | 
| 295 |  |  | 
| 296 | 10.4k |     if (st->comp == NULL) { | 
| 297 | 354k |         for (i = 0; i < st->num; i++) | 
| 298 | 354k |             if (st->data[i] == data) | 
| 299 | 4.02k |                 return i; | 
| 300 | 25 |         return -1; | 
| 301 | 4.05k |     } | 
| 302 |  |  | 
| 303 | 6.43k |     if (!st->sorted) { | 
| 304 | 0 |         if (st->num > 1) | 
| 305 | 0 |             qsort(st->data, st->num, sizeof(void *), st->comp); | 
| 306 | 0 |         st->sorted = 1; /* empty or single-element stack is considered sorted */ | 
| 307 | 0 |     } | 
| 308 | 6.43k |     if (data == NULL) | 
| 309 | 0 |         return -1; | 
| 310 | 6.43k |     r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp, | 
| 311 | 6.43k |                         ret_val_options); | 
| 312 |  |  | 
| 313 | 6.43k |     return r == NULL ? -1 : (int)((const void **)r - st->data); | 
| 314 | 6.43k | } | 
| 315 |  |  | 
| 316 |  | int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data) | 
| 317 | 53.7k | { | 
| 318 | 53.7k |     return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); | 
| 319 | 53.7k | } | 
| 320 |  |  | 
| 321 |  | int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data) | 
| 322 | 0 | { | 
| 323 | 0 |     return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); | 
| 324 | 0 | } | 
| 325 |  |  | 
| 326 |  | int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data) | 
| 327 | 141M | { | 
| 328 | 141M |     if (st == NULL) | 
| 329 | 0 |         return -1; | 
| 330 | 141M |     return OPENSSL_sk_insert(st, data, st->num); | 
| 331 | 141M | } | 
| 332 |  |  | 
| 333 |  | int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data) | 
| 334 | 0 | { | 
| 335 | 0 |     return OPENSSL_sk_insert(st, data, 0); | 
| 336 | 0 | } | 
| 337 |  |  | 
| 338 |  | void *OPENSSL_sk_shift(OPENSSL_STACK *st) | 
| 339 | 0 | { | 
| 340 | 0 |     if (st == NULL || st->num == 0) | 
| 341 | 0 |         return NULL; | 
| 342 | 0 |     return internal_delete(st, 0); | 
| 343 | 0 | } | 
| 344 |  |  | 
| 345 |  | void *OPENSSL_sk_pop(OPENSSL_STACK *st) | 
| 346 | 429k | { | 
| 347 | 429k |     if (st == NULL || st->num == 0) | 
| 348 | 5.54k |         return NULL; | 
| 349 | 423k |     return internal_delete(st, st->num - 1); | 
| 350 | 429k | } | 
| 351 |  |  | 
| 352 |  | void OPENSSL_sk_zero(OPENSSL_STACK *st) | 
| 353 | 0 | { | 
| 354 | 0 |     if (st == NULL || st->num == 0) | 
| 355 | 0 |         return; | 
| 356 | 0 |     memset(st->data, 0, sizeof(*st->data) * st->num); | 
| 357 | 0 |     st->num = 0; | 
| 358 | 0 | } | 
| 359 |  |  | 
| 360 |  | void OPENSSL_sk_pop_free(OPENSSL_STACK *st, OPENSSL_sk_freefunc func) | 
| 361 | 22.2M | { | 
| 362 | 22.2M |     int i; | 
| 363 |  |  | 
| 364 | 22.2M |     if (st == NULL) | 
| 365 | 5.09M |         return; | 
| 366 | 109M |     for (i = 0; i < st->num; i++) | 
| 367 | 92.6M |         if (st->data[i] != NULL) | 
| 368 | 92.4M |             func((char *)st->data[i]); | 
| 369 | 17.2M |     OPENSSL_sk_free(st); | 
| 370 | 17.2M | } | 
| 371 |  |  | 
| 372 |  | void OPENSSL_sk_free(OPENSSL_STACK *st) | 
| 373 | 100M | { | 
| 374 | 100M |     if (st == NULL) | 
| 375 | 27.6M |         return; | 
| 376 | 72.7M |     OPENSSL_free(st->data); | 
| 377 | 72.7M |     OPENSSL_free(st); | 
| 378 | 72.7M | } | 
| 379 |  |  | 
| 380 |  | int OPENSSL_sk_num(const OPENSSL_STACK *st) | 
| 381 | 646M | { | 
| 382 | 646M |     return st == NULL ? -1 : st->num; | 
| 383 | 646M | } | 
| 384 |  |  | 
| 385 |  | void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i) | 
| 386 | 874M | { | 
| 387 | 874M |     if (st == NULL || i < 0 || i >= st->num) | 
| 388 | 4.20k |         return NULL; | 
| 389 | 874M |     return (void *)st->data[i]; | 
| 390 | 874M | } | 
| 391 |  |  | 
| 392 |  | void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data) | 
| 393 | 3.04M | { | 
| 394 | 3.04M |     if (st == NULL || i < 0 || i >= st->num) | 
| 395 | 0 |         return NULL; | 
| 396 | 3.04M |     st->data[i] = data; | 
| 397 | 3.04M |     st->sorted = 0; | 
| 398 | 3.04M |     return (void *)st->data[i]; | 
| 399 | 3.04M | } | 
| 400 |  |  | 
| 401 |  | void OPENSSL_sk_sort(OPENSSL_STACK *st) | 
| 402 | 4.09M | { | 
| 403 | 4.09M |     if (st != NULL && !st->sorted && st->comp != NULL) { | 
| 404 | 4.09M |         if (st->num > 1) | 
| 405 | 78.3k |             qsort(st->data, st->num, sizeof(void *), st->comp); | 
| 406 | 4.09M |         st->sorted = 1; /* empty or single-element stack is considered sorted */ | 
| 407 | 4.09M |     } | 
| 408 | 4.09M | } | 
| 409 |  |  | 
| 410 |  | int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st) | 
| 411 | 9.21k | { | 
| 412 | 9.21k |     return st == NULL ? 1 : st->sorted; | 
| 413 | 9.21k | } |