From 246e09319c1d2a8140ffe1e5aeb1be26015696f0 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 28 Mar 2006 17:23:48 +0000 Subject: [PATCH] Fix bug where freed OIDs could be accessed in EVP_cleanup() by defering freeing in OBJ_cleanup(). --- CHANGES | 4 ++++ FAQ | 2 +- apps/apps.h | 4 ++-- apps/dgst.c | 5 +---- crypto/evp/names.c | 11 +++++++++++ crypto/objects/obj_dat.c | 18 ++++++++++++++++++ 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index bb006e21a1..b33ec32743 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,10 @@ Changes between 0.9.8a and 0.9.9 [xx XXX xxxx] + *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or + EVP_CIPHER structures to avoid later problems in EVP_cleanup(). + [Steve Henson] + *) New utilities pkey and pkeyparam. These are similar to algorithm specific utilities such as rsa, dsa, dsaparam etc except they processes any key type. diff --git a/FAQ b/FAQ index 9f6dc63d4f..a88765ef0f 100644 --- a/FAQ +++ b/FAQ @@ -430,7 +430,7 @@ encryption so these certificates are now obsolete. It doesn't: this extension is often the cause of confusion. -Consider a certificate chain A->B->C so that A signs, B and B signs C. Suppose +Consider a certificate chain A->B->C so that A signs B and B signs C. Suppose certificate C contains AKID. The purpose of this extension is to identify the authority certificate B. This diff --git a/apps/apps.h b/apps/apps.h index f7950d7a97..7a20d066c9 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -177,7 +177,7 @@ extern BIO *bio_err; ENGINE_load_builtin_engines(); setup_ui_method(); } while(0) # define apps_shutdown() \ do { CONF_modules_unload(1); destroy_ui_method(); \ - EVP_cleanup(); ENGINE_cleanup(); \ + OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \ CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \ ERR_free_strings(); } while(0) # else @@ -187,7 +187,7 @@ extern BIO *bio_err; setup_ui_method(); } while(0) # define apps_shutdown() \ do { CONF_modules_unload(1); destroy_ui_method(); \ - EVP_cleanup(); \ + OBJ_cleanup(); EVP_cleanup(); \ CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \ ERR_free_strings(); } while(0) # endif diff --git a/apps/dgst.c b/apps/dgst.c index 65b2ae34ba..0c9c351ebc 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -180,6 +180,7 @@ int MAIN(int argc, char **argv) { if (--argc < 1) break; engine= *(++argv); + e = setup_engine(bio_err, engine, 0); } #endif else if (strcmp(*argv,"-hex") == 0) @@ -257,10 +258,6 @@ int MAIN(int argc, char **argv) goto end; } -#ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); -#endif - in=BIO_new(BIO_s_file()); bmd=BIO_new(BIO_f_md()); if (debug) diff --git a/crypto/evp/names.c b/crypto/evp/names.c index 88c1e780dd..348df71cba 100644 --- a/crypto/evp/names.c +++ b/crypto/evp/names.c @@ -62,12 +62,16 @@ #include #include +extern int obj_cleanup_defer; +extern void check_defer(int nid); + int EVP_add_cipher(const EVP_CIPHER *c) { int r; r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); if (r == 0) return(0); + check_defer(c->nid); r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); return(r); } @@ -80,6 +84,7 @@ int EVP_add_digest(const EVP_MD *md) name=OBJ_nid2sn(md->type); r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md); if (r == 0) return(0); + check_defer(md->type); r=OBJ_NAME_add(OBJ_nid2ln(md->type),OBJ_NAME_TYPE_MD_METH,(const char *)md); if (r == 0) return(0); @@ -88,6 +93,7 @@ int EVP_add_digest(const EVP_MD *md) r=OBJ_NAME_add(OBJ_nid2sn(md->pkey_type), OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name); if (r == 0) return(0); + check_defer(md->pkey_type); r=OBJ_NAME_add(OBJ_nid2ln(md->pkey_type), OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name); } @@ -120,4 +126,9 @@ void EVP_cleanup(void) OBJ_NAME_cleanup(-1); EVP_PBE_cleanup(); + if (obj_cleanup_defer == 2) + { + obj_cleanup_defer = 0; + OBJ_cleanup(); + } } diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index 7a95c7795a..aca492d1df 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -208,8 +208,26 @@ static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ *) static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ *) static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ *) +/* The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting + * to use freed up OIDs. If neccessary the actual freeing up of OIDs is + * delayed. + */ + +int obj_cleanup_defer = 0; + +void check_defer(int nid) + { + if (obj_cleanup_defer && nid >= NUM_NID) + obj_cleanup_defer = 1; + } + void OBJ_cleanup(void) { + if (obj_cleanup_defer) + { + obj_cleanup_defer = 2; + return ; + } if (added == NULL) return; added->down_load=0; lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ -- 2.25.1