[openssl-commits] [openssl] master update

Andy Polyakov appro at openssl.org
Tue Oct 3 10:52:05 UTC 2017


The branch master has been updated
       via  270a4bba49849de7f928f4fab186205abd132411 (commit)
       via  8e8e507ed720ca0acbeb15e238bf99519a9e7aab (commit)
      from  2dbfa8444bdf7669a54006c4a83d1e60ba374528 (commit)


- Log -----------------------------------------------------------------
commit 270a4bba49849de7f928f4fab186205abd132411
Author: FdaSilvaYY <fdasilvayy at gmail.com>
Date:   Thu Sep 28 23:30:22 2017 +0200

    Use more pre-allocation
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4379)

commit 8e8e507ed720ca0acbeb15e238bf99519a9e7aab
Author: FdaSilvaYY <fdasilvayy at gmail.com>
Date:   Thu Sep 28 22:03:26 2017 +0200

    Postpone allocation of STACK internal storage ... until a first push(),
    insert() or an explicit call to OPENSSL_sk_reserve
    
    Factorise STACK item deletion code
    
    Reviewed-by: Andy Polyakov <appro at openssl.org>
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4379)

-----------------------------------------------------------------------

Summary of changes:
 crypto/stack/stack.c     | 96 +++++++++++++++++++++++++++++++-----------------
 crypto/x509v3/v3_alt.c   | 58 ++++++++++++++++++-----------
 crypto/x509v3/v3_cpols.c | 23 +++++++-----
 crypto/x509v3/v3_crld.c  | 23 +++++-------
 crypto/x509v3/v3_extku.c |  9 +++--
 crypto/x509v3/v3_pmaps.c | 10 +++--
 6 files changed, 135 insertions(+), 84 deletions(-)

diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
index e71da73..5c9d487 100644
--- a/crypto/stack/stack.c
+++ b/crypto/stack/stack.c
@@ -55,6 +55,13 @@ OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk)
     /* direct structure assignment */
     *ret = *sk;
 
+    if (sk->num == 0) {
+        /* postpone |ret->data| allocation */
+        ret->data = NULL;
+        ret->num_alloc = 0;
+        return ret;
+    }
+    /* duplicate |sk->data| content */
     if ((ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc)) == NULL)
         goto err;
     memcpy(ret->data, sk->data, sizeof(void *) * sk->num);
@@ -80,6 +87,13 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
     /* direct structure assignment */
     *ret = *sk;
 
+    if (sk->num == 0) {
+        /* postpone |ret| data allocation */
+        ret->data = NULL;
+        ret->num_alloc = 0;
+        return ret;
+    }
+
     ret->num_alloc = sk->num > min_nodes ? sk->num : min_nodes;
     ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc);
     if (ret->data == NULL) {
@@ -103,41 +117,35 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
 
 OPENSSL_STACK *OPENSSL_sk_new_null(void)
 {
-    return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL);
+    return OPENSSL_zalloc(sizeof(OPENSSL_STACK));
 }
 
 OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c)
 {
-    OPENSSL_STACK *ret;
-
-    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
-        goto err;
-    if ((ret->data = OPENSSL_zalloc(sizeof(*ret->data) * min_nodes)) == NULL)
-        goto err;
-    ret->comp = c;
-    ret->num_alloc = min_nodes;
-    return (ret);
+    OPENSSL_STACK *ret = OPENSSL_sk_new_null();
 
- err:
-    OPENSSL_free(ret);
-    return (NULL);
+    if (ret != NULL)
+        ret->comp = c;
+    return ret;
 }
 
 /*
  * Calculate the array growth based on the target size.
  *
- * The growth faction is a rational number and is defined by a numerator
+ * The growth fraction is a rational number and is defined by a numerator
  * and a denominator.  According to Andrew Koenig in his paper "Why Are
  * Vectors Efficient?" from JOOP 11(5) 1998, this factor should be less
  * than the golden ratio (1.618...).
  *
- * We use 3/2 = 1.5 for simplicty of calculation and overflow checking.
+ * We use 3/2 = 1.5 for simplicity of calculation and overflow checking.
  * Another option 8/5 = 1.6 allows for slightly faster growth, although safe
  * computation is more difficult.
  *
  * The limit to avoid overflow is spot on.  The modulo three correction term
  * ensures that the limit is the largest number than can be expanded by the
  * growth factor without exceeding the hard limit.
+ *
+ * Do not call it with |current| lower than 2, or it will infinitely loop.
  */
 static ossl_inline int compute_growth(int target, int current)
 {
@@ -154,6 +162,7 @@ static ossl_inline int compute_growth(int target, int current)
     return current;
 }
 
+/* internal STACK storage allocation */
 static int sk_reserve(OPENSSL_STACK *st, int n, int exact)
 {
     const void **tmpdata;
@@ -168,6 +177,19 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact)
     if (num_alloc < min_nodes)
         num_alloc = min_nodes;
 
+    /* If |st->data| allocation was postponed */
+    if (st->data == NULL) {
+        /*
+         * At this point, |st->num_alloc| and |st->num| are 0;
+         * so |num_alloc| value is |n| or |min_nodes| if greater than |n|.
+         */
+        st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc);
+        if (st->data == NULL)
+            return 0;
+        st->num_alloc = num_alloc;
+        return 1;
+    }
+
     if (!exact) {
         if (num_alloc <= st->num_alloc)
             return 1;
@@ -217,29 +239,34 @@ int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc)
     return st->num;
 }
 
+static ossl_inline void *internal_delete(OPENSSL_STACK *st, int loc)
+{
+    const void *ret = st->data[loc];
+
+    if (loc != st->num - 1)
+         memmove(&st->data[loc], &st->data[loc + 1],
+                 sizeof(st->data[0]) * (st->num - loc - 1));
+    st->num--;
+
+    return (void *)ret;
+}
+
 void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p)
 {
     int i;
 
     for (i = 0; i < st->num; i++)
         if (st->data[i] == p)
-            return OPENSSL_sk_delete(st, i);
+            return internal_delete(st, i);
     return NULL;
 }
 
 void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc)
 {
-    const void *ret;
-
     if (st == NULL || loc < 0 || loc >= st->num)
         return NULL;
 
-    ret = st->data[loc];
-    if (loc != st->num - 1)
-         memmove(&st->data[loc], &st->data[loc + 1],
-                 sizeof(st->data[0]) * (st->num - loc - 1));
-    st->num--;
-    return (void *)ret;
+    return internal_delete(st, loc);
 }
 
 static int internal_find(OPENSSL_STACK *st, const void *data,
@@ -248,7 +275,7 @@ static int internal_find(OPENSSL_STACK *st, const void *data,
     const void *r;
     int i;
 
-    if (st == NULL)
+    if (st == NULL || st->num == 0)
         return -1;
 
     if (st->comp == NULL) {
@@ -279,7 +306,9 @@ int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data)
 
 int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
 {
-    return (OPENSSL_sk_insert(st, data, st->num));
+    if (st == NULL)
+        return -1;
+    return OPENSSL_sk_insert(st, data, st->num);
 }
 
 int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data)
@@ -290,19 +319,19 @@ int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data)
 void *OPENSSL_sk_shift(OPENSSL_STACK *st)
 {
     if (st == NULL)
-        return (NULL);
+        return NULL;
     if (st->num <= 0)
-        return (NULL);
-    return (OPENSSL_sk_delete(st, 0));
+        return NULL;
+    return internal_delete(st, 0);
 }
 
 void *OPENSSL_sk_pop(OPENSSL_STACK *st)
 {
     if (st == NULL)
-        return (NULL);
+        return NULL;
     if (st->num <= 0)
-        return (NULL);
-    return (OPENSSL_sk_delete(st, st->num - 1));
+        return NULL;
+    return internal_delete(st, st->num - 1);
 }
 
 void OPENSSL_sk_zero(OPENSSL_STACK *st)
@@ -360,7 +389,8 @@ void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data)
 void OPENSSL_sk_sort(OPENSSL_STACK *st)
 {
     if (st && !st->sorted && st->comp != NULL) {
-        qsort(st->data, st->num, sizeof(void *), st->comp);
+        if (st->data != NULL)
+            qsort(st->data, st->num, sizeof(void *), st->comp);
         st->sorted = 1;
     }
 }
diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c
index 598cffd..f082388 100644
--- a/crypto/x509v3/v3_alt.c
+++ b/crypto/x509v3/v3_alt.c
@@ -201,25 +201,28 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
                                      X509V3_CTX *ctx,
                                      STACK_OF(CONF_VALUE) *nval)
 {
-    GENERAL_NAMES *gens = NULL;
-    CONF_VALUE *cnf;
+    GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();
+    const int num = sk_CONF_VALUE_num(nval);
     int i;
 
-    if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
+    if (gens == NULL || !sk_GENERAL_NAME_reserve(gens, num)) {
         X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE);
+        sk_GENERAL_NAME_free(gens);
         return NULL;
     }
-    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
-        cnf = sk_CONF_VALUE_value(nval, i);
+    for (i = 0; i < num; i++) {
+        CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
+
         if (!name_cmp(cnf->name, "issuer")
             && cnf->value && strcmp(cnf->value, "copy") == 0) {
             if (!copy_issuer(ctx, gens))
                 goto err;
         } else {
-            GENERAL_NAME *gen;
-            if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
+            GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf);
+
+            if (gen == NULL)
                 goto err;
-            sk_GENERAL_NAME_push(gens, gen);
+            sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */
         }
     }
     return gens;
@@ -235,7 +238,7 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
     GENERAL_NAMES *ialt;
     GENERAL_NAME *gen;
     X509_EXTENSION *ext;
-    int i;
+    int i, num;
 
     if (ctx && (ctx->flags == CTX_TEST))
         return 1;
@@ -252,12 +255,15 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
         goto err;
     }
 
-    for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
+    num = sk_GENERAL_NAME_num(ialt);
+    if (!sk_GENERAL_NAME_reserve(gens, num)) {
+        X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    for (i = 0; i < num; i++) {
         gen = sk_GENERAL_NAME_value(ialt, i);
-        if (!sk_GENERAL_NAME_push(gens, gen)) {
-            X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE);
-            goto err;
-        }
+        sk_GENERAL_NAME_push(gens, gen);     /* no failure as it was reserved */
     }
     sk_GENERAL_NAME_free(ialt);
 
@@ -272,15 +278,19 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
                                       X509V3_CTX *ctx,
                                       STACK_OF(CONF_VALUE) *nval)
 {
-    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAMES *gens;
     CONF_VALUE *cnf;
+    const int num = sk_CONF_VALUE_num(nval);
     int i;
 
-    if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
+    gens = sk_GENERAL_NAME_new_null();
+    if (gens == NULL || !sk_GENERAL_NAME_reserve(gens, num)) {
         X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE);
+        sk_GENERAL_NAME_free(gens);
         return NULL;
     }
-    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+
+    for (i = 0; i < num; i++) {
         cnf = sk_CONF_VALUE_value(nval, i);
         if (!name_cmp(cnf->name, "email")
             && cnf->value && strcmp(cnf->value, "copy") == 0) {
@@ -294,7 +304,7 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
             GENERAL_NAME *gen;
             if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
                 goto err;
-            sk_GENERAL_NAME_push(gens, gen);
+            sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */
         }
     }
     return gens;
@@ -365,19 +375,23 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
                                  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 {
     GENERAL_NAME *gen;
-    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAMES *gens;
     CONF_VALUE *cnf;
+    const int num = sk_CONF_VALUE_num(nval);
     int i;
 
-    if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
+    gens = sk_GENERAL_NAME_new_null();
+    if (gens == NULL || !sk_GENERAL_NAME_reserve(gens, num)) {
         X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE);
+        sk_GENERAL_NAME_free(gens);
         return NULL;
     }
-    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+
+    for (i = 0; i < num; i++) {
         cnf = sk_CONF_VALUE_value(nval, i);
         if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
             goto err;
-        sk_GENERAL_NAME_push(gens, gen);
+        sk_GENERAL_NAME_push(gens, gen);    /* no failure as it was reserved */
     }
     return gens;
  err:
diff --git a/crypto/x509v3/v3_cpols.c b/crypto/x509v3/v3_cpols.c
index ea65e07..56460a3 100644
--- a/crypto/x509v3/v3_cpols.c
+++ b/crypto/x509v3/v3_cpols.c
@@ -88,26 +88,30 @@ IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)
 static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
                                          X509V3_CTX *ctx, const char *value)
 {
-    STACK_OF(POLICYINFO) *pols = NULL;
+    STACK_OF(POLICYINFO) *pols;
     char *pstr;
     POLICYINFO *pol;
     ASN1_OBJECT *pobj;
-    STACK_OF(CONF_VALUE) *vals;
+    STACK_OF(CONF_VALUE) *vals = X509V3_parse_list(value);
     CONF_VALUE *cnf;
+    const int num = sk_CONF_VALUE_num(vals);
     int i, ia5org;
-    pols = sk_POLICYINFO_new_null();
-    if (pols == NULL) {
-        X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
-        return NULL;
-    }
-    vals = X509V3_parse_list(value);
+
     if (vals == NULL) {
         X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB);
+        return NULL;
+    }
+
+    pols = sk_POLICYINFO_new_null();
+    if (pols == NULL || !sk_POLICYINFO_reserve(pols, num)) {
+        X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
         goto err;
     }
+
     ia5org = 0;
-    for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+    for (i = 0; i < num; i++) {
         cnf = sk_CONF_VALUE_value(vals, i);
+
         if (cnf->value || !cnf->name) {
             X509V3err(X509V3_F_R2I_CERTPOL,
                       X509V3_R_INVALID_POLICY_IDENTIFIER);
@@ -241,7 +245,6 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
  err:
     POLICYINFO_free(pol);
     return NULL;
-
 }
 
 static int displaytext_get_tag_len(const char *tagstr)
diff --git a/crypto/x509v3/v3_crld.c b/crypto/x509v3/v3_crld.c
index c4c77f1..085a90d 100644
--- a/crypto/x509v3/v3_crld.c
+++ b/crypto/x509v3/v3_crld.c
@@ -205,8 +205,8 @@ static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
 {
     int i;
     CONF_VALUE *cnf;
-    DIST_POINT *point = NULL;
-    point = DIST_POINT_new();
+    DIST_POINT *point = DIST_POINT_new();
+
     if (point == NULL)
         goto err;
     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -237,16 +237,19 @@ static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
 static void *v2i_crld(const X509V3_EXT_METHOD *method,
                       X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 {
-    STACK_OF(DIST_POINT) *crld = NULL;
+    STACK_OF(DIST_POINT) *crld;
     GENERAL_NAMES *gens = NULL;
     GENERAL_NAME *gen = NULL;
     CONF_VALUE *cnf;
+    const int num = sk_CONF_VALUE_num(nval);
     int i;
 
-    if ((crld = sk_DIST_POINT_new_null()) == NULL)
+    crld = sk_DIST_POINT_new_null();
+    if (crld == NULL || !sk_DIST_POINT_reserve(crld, num))
         goto merr;
-    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+    for (i = 0; i < num; i++) {
         DIST_POINT *point;
+
         cnf = sk_CONF_VALUE_value(nval, i);
         if (!cnf->value) {
             STACK_OF(CONF_VALUE) *dpsect;
@@ -257,10 +260,7 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method,
             X509V3_section_free(ctx, dpsect);
             if (!point)
                 goto err;
-            if (!sk_DIST_POINT_push(crld, point)) {
-                DIST_POINT_free(point);
-                goto merr;
-            }
+            sk_DIST_POINT_push(crld, point); /* no failure as it was reserved */
         } else {
             if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
                 goto err;
@@ -271,10 +271,7 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method,
             gen = NULL;
             if ((point = DIST_POINT_new()) == NULL)
                 goto merr;
-            if (!sk_DIST_POINT_push(crld, point)) {
-                DIST_POINT_free(point);
-                goto merr;
-            }
+            sk_DIST_POINT_push(crld, point); /* no failure as it was reserved */
             if ((point->distpoint = DIST_POINT_NAME_new()) == NULL)
                 goto merr;
             point->distpoint->name.fullname = gens;
diff --git a/crypto/x509v3/v3_extku.c b/crypto/x509v3/v3_extku.c
index bae755e..6cb0d2c 100644
--- a/crypto/x509v3/v3_extku.c
+++ b/crypto/x509v3/v3_extku.c
@@ -74,14 +74,17 @@ static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
     char *extval;
     ASN1_OBJECT *objtmp;
     CONF_VALUE *val;
+    const int num = sk_CONF_VALUE_num(nval);
     int i;
 
-    if ((extku = sk_ASN1_OBJECT_new_null()) == NULL) {
+    extku = sk_ASN1_OBJECT_new_null();
+    if (extku == NULL || !sk_ASN1_OBJECT_reserve(extku, num)) {
         X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE);
+        sk_ASN1_OBJECT_free(extku);
         return NULL;
     }
 
-    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+    for (i = 0; i < num; i++) {
         val = sk_CONF_VALUE_value(nval, i);
         if (val->value)
             extval = val->value;
@@ -94,7 +97,7 @@ static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
             X509V3_conf_err(val);
             return NULL;
         }
-        sk_ASN1_OBJECT_push(extku, objtmp);
+        sk_ASN1_OBJECT_push(extku, objtmp);  /* no failure as it was reserved */
     }
     return extku;
 }
diff --git a/crypto/x509v3/v3_pmaps.c b/crypto/x509v3/v3_pmaps.c
index 73f4ec2..b9f8f02 100644
--- a/crypto/x509v3/v3_pmaps.c
+++ b/crypto/x509v3/v3_pmaps.c
@@ -52,6 +52,7 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
     int i;
     char obj_tmp1[80];
     char obj_tmp2[80];
+
     for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
         pmap = sk_POLICY_MAPPING_value(pmaps, i);
         i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
@@ -64,18 +65,21 @@ static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
 static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
                                  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
 {
-    POLICY_MAPPINGS *pmaps = NULL;
     POLICY_MAPPING *pmap = NULL;
     ASN1_OBJECT *obj1 = NULL, *obj2 = NULL;
     CONF_VALUE *val;
+    POLICY_MAPPINGS *pmaps;
+    const int num = sk_CONF_VALUE_num(nval);
     int i;
 
     if ((pmaps = sk_POLICY_MAPPING_new_null()) == NULL) {
         X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
+    if (!sk_POLICY_MAPPING_reserve(pmaps, num))
+        goto err;
 
-    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+    for (i = 0; i < num; i++) {
         val = sk_CONF_VALUE_value(nval, i);
         if (!val->value || !val->name) {
             X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,
@@ -99,7 +103,7 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
         pmap->issuerDomainPolicy = obj1;
         pmap->subjectDomainPolicy = obj2;
         obj1 = obj2 = NULL;
-        sk_POLICY_MAPPING_push(pmaps, pmap);
+        sk_POLICY_MAPPING_push(pmaps, pmap); /* no failure as it was reserved */
     }
     return pmaps;
  err:


More information about the openssl-commits mailing list