This adds return value check for sk_X509_push. In error case, allocated memories are freed at 'export_end:'. After this diff, I would like to add more another return value check.
ok? Index: pkcs12.c =================================================================== RCS file: /cvs/src/usr.bin/openssl/pkcs12.c,v retrieving revision 1.20 diff -u -p -u -p -r1.20 pkcs12.c --- pkcs12.c 28 Apr 2022 15:42:10 -0000 1.20 +++ pkcs12.c 28 Apr 2022 18:59:39 -0000 @@ -613,6 +613,9 @@ pkcs12_main(int argc, char **argv) EVP_PKEY *key = NULL; X509 *ucert = NULL, *x = NULL; STACK_OF(X509) *certs = NULL; + STACK_OF(X509) *morecerts = NULL; + STACK_OF(X509) *chain2 = NULL; + X509_STORE *store = NULL; const EVP_MD *macmd = NULL; unsigned char *catmp = NULL; int i; @@ -664,23 +667,24 @@ pkcs12_main(int argc, char **argv) /* Add any more certificates asked for */ if (pkcs12_config.certfile != NULL) { - STACK_OF(X509) *morecerts = NULL; if ((morecerts = load_certs(bio_err, pkcs12_config.certfile, FORMAT_PEM, NULL, "certificates from certfile")) == NULL) goto export_end; - while (sk_X509_num(morecerts) > 0) - sk_X509_push(certs, sk_X509_shift(morecerts)); + while (sk_X509_num(morecerts) > 0) { + if (!sk_X509_push(certs, sk_X509_shift(morecerts))) + goto export_end; + } sk_X509_free(morecerts); + morecerts = NULL; } /* If chaining get chain from user cert */ if (pkcs12_config.chain) { int vret; - STACK_OF(X509) *chain2; - X509_STORE *store = X509_STORE_new(); - if (store == NULL) { + + if ((store = X509_STORE_new()) == NULL) { BIO_printf(bio_err, "Memory allocation error\n"); goto export_end; @@ -691,15 +695,19 @@ pkcs12_main(int argc, char **argv) vret = get_cert_chain(ucert, store, &chain2); X509_STORE_free(store); + store = NULL; if (vret == X509_V_OK) { /* Exclude verified certificate */ - for (i = 1; i < sk_X509_num(chain2); i++) - sk_X509_push(certs, sk_X509_value( - chain2, i)); + for (i = 1; i < sk_X509_num(chain2); i++) { + if (!sk_X509_push(certs, sk_X509_value( + chain2, i))) + goto export_end; + } /* Free first certificate */ X509_free(sk_X509_value(chain2, 0)); sk_X509_free(chain2); + chain2 = NULL; } else { if (vret != X509_V_ERR_UNSPECIFIED) BIO_printf(bio_err, @@ -765,8 +773,11 @@ pkcs12_main(int argc, char **argv) export_end: EVP_PKEY_free(key); - sk_X509_pop_free(certs, X509_free); X509_free(ucert); + sk_X509_pop_free(certs, X509_free); + sk_X509_pop_free(morecerts, X509_free); + sk_X509_pop_free(chain2, X509_free); + X509_STORE_free(store); goto end;