Don't leak memory in v2i_POLICY_MAPPINGS() on error path
[openssl.git] / crypto / x509v3 / v3_pmaps.c
index 959b678b12d8b3ce3187325a94df32bb859bdb07..73f4ec24670131f792349d118122ba0183c7038d 100644 (file)
@@ -64,9 +64,9 @@ 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;
-    POLICY_MAPPING *pmap;
-    ASN1_OBJECT *obj1, *obj2;
+    POLICY_MAPPINGS *pmaps = NULL;
+    POLICY_MAPPING *pmap = NULL;
+    ASN1_OBJECT *obj1 = NULL, *obj2 = NULL;
     CONF_VALUE *val;
     int i;
 
@@ -78,30 +78,33 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
         val = sk_CONF_VALUE_value(nval, i);
         if (!val->value || !val->name) {
-            sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
             X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,
                       X509V3_R_INVALID_OBJECT_IDENTIFIER);
             X509V3_conf_err(val);
-            return NULL;
+            goto err;
         }
         obj1 = OBJ_txt2obj(val->name, 0);
         obj2 = OBJ_txt2obj(val->value, 0);
         if (!obj1 || !obj2) {
-            sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
             X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,
                       X509V3_R_INVALID_OBJECT_IDENTIFIER);
             X509V3_conf_err(val);
-            return NULL;
+            goto err;
         }
         pmap = POLICY_MAPPING_new();
         if (pmap == NULL) {
-            sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
             X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
-            return NULL;
+            goto err;
         }
         pmap->issuerDomainPolicy = obj1;
         pmap->subjectDomainPolicy = obj2;
+        obj1 = obj2 = NULL;
         sk_POLICY_MAPPING_push(pmaps, pmap);
     }
     return pmaps;
+ err:
+    ASN1_OBJECT_free(obj1);
+    ASN1_OBJECT_free(obj2);
+    sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+    return NULL;
 }