Fix bug where freed OIDs could be accessed in EVP_cleanup() by

defering freeing in OBJ_cleanup().
This commit is contained in:
Dr. Stephen Henson 2006-03-28 17:23:48 +00:00
parent f7a3296d8c
commit 246e09319c
6 changed files with 37 additions and 7 deletions

View File

@ -4,6 +4,10 @@
Changes between 0.9.8a and 0.9.9 [xx XXX xxxx] 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 *) New utilities pkey and pkeyparam. These are similar to algorithm specific
utilities such as rsa, dsa, dsaparam etc except they processes any key utilities such as rsa, dsa, dsaparam etc except they processes any key
type. type.

2
FAQ
View File

@ -430,7 +430,7 @@ encryption so these certificates are now obsolete.
It doesn't: this extension is often the cause of confusion. 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. certificate C contains AKID.
The purpose of this extension is to identify the authority certificate B. This The purpose of this extension is to identify the authority certificate B. This

View File

@ -177,7 +177,7 @@ extern BIO *bio_err;
ENGINE_load_builtin_engines(); setup_ui_method(); } while(0) ENGINE_load_builtin_engines(); setup_ui_method(); } while(0)
# define apps_shutdown() \ # define apps_shutdown() \
do { CONF_modules_unload(1); destroy_ui_method(); \ 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); \ CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \
ERR_free_strings(); } while(0) ERR_free_strings(); } while(0)
# else # else
@ -187,7 +187,7 @@ extern BIO *bio_err;
setup_ui_method(); } while(0) setup_ui_method(); } while(0)
# define apps_shutdown() \ # define apps_shutdown() \
do { CONF_modules_unload(1); destroy_ui_method(); \ do { CONF_modules_unload(1); destroy_ui_method(); \
EVP_cleanup(); \ OBJ_cleanup(); EVP_cleanup(); \
CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \ CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \
ERR_free_strings(); } while(0) ERR_free_strings(); } while(0)
# endif # endif

View File

@ -180,6 +180,7 @@ int MAIN(int argc, char **argv)
{ {
if (--argc < 1) break; if (--argc < 1) break;
engine= *(++argv); engine= *(++argv);
e = setup_engine(bio_err, engine, 0);
} }
#endif #endif
else if (strcmp(*argv,"-hex") == 0) else if (strcmp(*argv,"-hex") == 0)
@ -257,10 +258,6 @@ int MAIN(int argc, char **argv)
goto end; goto end;
} }
#ifndef OPENSSL_NO_ENGINE
e = setup_engine(bio_err, engine, 0);
#endif
in=BIO_new(BIO_s_file()); in=BIO_new(BIO_s_file());
bmd=BIO_new(BIO_f_md()); bmd=BIO_new(BIO_f_md());
if (debug) if (debug)

View File

@ -62,12 +62,16 @@
#include <openssl/objects.h> #include <openssl/objects.h>
#include <openssl/x509.h> #include <openssl/x509.h>
extern int obj_cleanup_defer;
extern void check_defer(int nid);
int EVP_add_cipher(const EVP_CIPHER *c) int EVP_add_cipher(const EVP_CIPHER *c)
{ {
int r; int r;
r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
if (r == 0) return(0); 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); r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
return(r); return(r);
} }
@ -80,6 +84,7 @@ int EVP_add_digest(const EVP_MD *md)
name=OBJ_nid2sn(md->type); name=OBJ_nid2sn(md->type);
r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md); r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md);
if (r == 0) return(0); 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); r=OBJ_NAME_add(OBJ_nid2ln(md->type),OBJ_NAME_TYPE_MD_METH,(const char *)md);
if (r == 0) return(0); 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), r=OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name); OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
if (r == 0) return(0); if (r == 0) return(0);
check_defer(md->pkey_type);
r=OBJ_NAME_add(OBJ_nid2ln(md->pkey_type), r=OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name); OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,name);
} }
@ -120,4 +126,9 @@ void EVP_cleanup(void)
OBJ_NAME_cleanup(-1); OBJ_NAME_cleanup(-1);
EVP_PBE_cleanup(); EVP_PBE_cleanup();
if (obj_cleanup_defer == 2)
{
obj_cleanup_defer = 0;
OBJ_cleanup();
}
} }

View File

@ -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(cleanup2, ADDED_OBJ *)
static IMPLEMENT_LHASH_DOALL_FN(cleanup3, 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) void OBJ_cleanup(void)
{ {
if (obj_cleanup_defer)
{
obj_cleanup_defer = 2;
return ;
}
if (added == NULL) return; if (added == NULL) return;
added->down_load=0; added->down_load=0;
lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */ lh_doall(added,LHASH_DOALL_FN(cleanup1)); /* zero counters */