[Pkg-openssl-devel] Bug#670581: Bug#670581: openssl: ntpd segfaults with error 4 in libcrypto.so.0.9.8 on Debian squeeze
Andris Kalnozols
andris at hpl.hp.com
Tue May 1 06:54:20 UTC 2012
I believe I found the smoking gun by breaking out the call
to EVP_get_digestbynid(crypto_nid) and testing its return
value:
> --- ntp_crypto.c.orig 2009-12-08 23:36:35.000000000 -0800
> +++ ntp_crypto.c 2012-04-30 22:44:46.094602274 -0700
> @@ -197,6 +197,7 @@
> )
> {
> EVP_MD_CTX ctx; /* message digest context */
> + const EVP_MD *type;
> u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */
> keyid_t keyid; /* key identifer */
> u_int32 header[10]; /* data in network byte order */
> @@ -229,7 +230,43 @@
> hdlen = 10 * sizeof(u_int32);
> break;
> }
> - EVP_DigestInit(&ctx, EVP_get_digestbynid(crypto_nid));
> + if ((type = EVP_get_digestbynid(crypto_nid)) == NULL)
> + msyslog(LOG_ERR, "EVP_get_digestbynid(KEY_TYPE_MD5) "
> + "returned NULL");
> + EVP_DigestInit(&ctx, type);
> EVP_DigestUpdate(&ctx, (u_char *)header, hdlen);
> EVP_DigestFinal(&ctx, dgst, &len);
> memcpy(&keyid, dgst, 4);
Sure enough, this routine returns NULL before the program segfaults.
A web search led me to this:
>
http://stackoverflow.com/questions/6762054/evp-get-digestbyname-what-is-this
Indeed, the Debian man page for evp_get_digestbynid(3) has this
important information:
> EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj() return
> an EVP_MD structure when passed a digest name, a digest NID or an
ASN1_OBJECT
> structure respectively. The digest table must be initialized using,
for example,
> OpenSSL_add_all_digests() for these functions to work.
My search of the NTP source code for references to
"OpenSSL_add_all_*" showed the following two locations:
libntp/ssl_init.c:
------------------
> #ifdef OPENSSL
> #include "openssl/err.h"
> #include "openssl/rand.h"
>
>
> int ssl_init_done;
>
> void
> ssl_init(void)
> {
> if (ssl_init_done)
> return;
>
> ERR_load_crypto_strings();
> OpenSSL_add_all_algorithms();
>
> ssl_init_done = 1;
> }
>
>
> void
> ssl_check_version(void)
> {
> INIT_SSL();
> }
> #endif /* OPENSSL */
include/ntp_stdlib.h:
---------------------
> /* ssl_init.c */
> #ifdef OPENSSL
> extern void ssl_init (void);
> extern void ssl_check_version (void);
> extern int ssl_init_done;
> #define INIT_SSL() \
> do { \
> if (!ssl_init_done) \
> ssl_init(); \
> } while (0)
> #else /* !OPENSSL follows */
> #define INIT_SSL() do {} while (0)
> #endif
However, I can't find where the ntpd program ever calls ssl_init()
or the INIT_SSL() macro. So I'm betting that this problem will go
away once I find the proper place to call this important routine.
Perhaps you can keep this ticket open until I can confirm my hunch.
It shouldn't take too long.
Thanks,
Andris
More information about the Pkg-openssl-devel
mailing list