Bug 1852350
| Summary: | httpd/mod_proxy_http/mod_ssl aborted when sending a client cert to backend server [rhel-7.9.z] | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Hisanobu Okuda <hokuda> | ||||||||
| Component: | httpd | Assignee: | Luboš Uhliarik <luhliari> | ||||||||
| Status: | CLOSED ERRATA | QA Contact: | icesalov | ||||||||
| Severity: | unspecified | Docs Contact: | |||||||||
| Priority: | urgent | ||||||||||
| Version: | 7.8 | CC: | bnater, dmasirka, jorton, jreznik, luhliari, redhat | ||||||||
| Target Milestone: | rc | Keywords: | ZStream | ||||||||
| Target Release: | --- | ||||||||||
| Hardware: | Unspecified | ||||||||||
| OS: | Unspecified | ||||||||||
| Whiteboard: | |||||||||||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |||||||||
| Doc Text: | Story Points: | --- | |||||||||
| Clone Of: | |||||||||||
| : | 1861380 (view as bug list) | Environment: | |||||||||
| Last Closed: | 2020-11-10 13:10:55 UTC | Type: | Bug | ||||||||
| Regression: | --- | Mount Type: | --- | ||||||||
| Documentation: | --- | CRM: | |||||||||
| Verified Versions: | Category: | --- | |||||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||||
| Embargoed: | |||||||||||
| Attachments: |
|
||||||||||
|
Description
Hisanobu Okuda
2020-06-30 08:22:55 UTC
Created attachment 1699255 [details]
core
Created attachment 1699256 [details]
rpm-qa
The issue occurs when EVP_PKEY.reference is unexpectedly 0.
I set the conditional breakpoint at CRYPTO_add_lock to hit the breakpoint with the same "pointer"(==&(EVP_PKEY.reference)):
(gdb) info breakpoints
Num Type Disp Enb Address What
3 breakpoint keep y 0x00007f00fc3e7ff0 in CRYPTO_add_lock at cryptlib.c:601
stop only if pointer == 0x559d90ba7958
breakpoint already hit 54 times
(gdb)
And accessed with the URL http://localhost:80/foo/, then the breakpoint was hit 8 times.
1:
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=1, type=5, file=0x7f00fca7a4b8 "ssl_engine_kernel.c", line=1571) at cryptlib.c:601
#1 0x00007f00fca699bf in ssl_callback_proxy_cert (ssl=<optimized out>, x509=0x7f00f92ef518, pkey=0x7f00f92ef520)
at ssl_engine_kernel.c:1571
#2 0x00007f00fc8028f9 in ssl3_send_client_certificate (s=s@entry=0x7f00ec02db10) at s3_clnt.c:3450
#3 0x00007f00fc802ecf in ssl3_connect (s=0x7f00ec02db10) at s3_clnt.c:421
#4 0x00007f00fc80ce7e in ssl23_get_server_hello (s=0x7f00ec02db10) at s23_clnt.c:799
#5 ssl23_connect (s=0x7f00ec02db10) at s23_clnt.c:228
#6 0x00007f00fca640d8 in ssl_io_filter_handshake (filter_ctx=filter_ctx@entry=0x7f00ec0071c0) at ssl_engine_io.c:1086
2:
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=1, type=10, file=0x7f00fc836540 "ssl_rsa.c", line=232) at cryptlib.c:601
#1 0x00007f00fc82b1e7 in ssl_set_pkey (c=0x7f00ec022410, pkey=0x559d90ba7950) at ssl_rsa.c:232
#2 0x00007f00fc82bb66 in SSL_use_PrivateKey (ssl=ssl@entry=0x7f00ec02db10, pkey=<optimized out>) at ssl_rsa.c:314
#3 0x00007f00fc8029ab in ssl3_send_client_certificate (s=s@entry=0x7f00ec02db10) at s3_clnt.c:3458
#4 0x00007f00fc802ecf in ssl3_connect (s=0x7f00ec02db10) at s3_clnt.c:421
#5 0x00007f00fc80ce7e in ssl23_get_server_hello (s=0x7f00ec02db10) at s23_clnt.c:799
#6 ssl23_connect (s=0x7f00ec02db10) at s23_clnt.c:228
#7 0x00007f00fca640d8 in ssl_io_filter_handshake (filter_ctx=filter_ctx@entry=0x7f00ec0071c0) at ssl_engine_io.c:1086
3:
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=-1, type=10, file=0x7f00fc569c8f "p_lib.c", line=391) at cryptlib.c:601
#1 0x00007f00fc4ae529 in EVP_PKEY_free (x=0x559d90ba7950) at p_lib.c:391
#2 0x00007f00fc80292d in ssl3_send_client_certificate (s=s@entry=0x7f00ec02db10) at s3_clnt.c:3469
#3 0x00007f00fc802ecf in ssl3_connect (s=0x7f00ec02db10) at s3_clnt.c:421
#4 0x00007f00fc80ce7e in ssl23_get_server_hello (s=0x7f00ec02db10) at s23_clnt.c:799
#5 ssl23_connect (s=0x7f00ec02db10) at s23_clnt.c:228
#6 0x00007f00fca640d8 in ssl_io_filter_handshake (filter_ctx=filter_ctx@entry=0x7f00ec0071c0) at ssl_engine_io.c:1086
4:
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=1, type=10, file=0x7f00fc5626fb "pmeth_lib.c", line=186) at cryptlib.c:601
#1 0x00007f00fc4b3c9d in int_ctx_new (pkey=pkey@entry=0x559d90ba7950, e=e@entry=0x0, id=<optimized out>, id@entry=-1)
at pmeth_lib.c:186
#2 0x00007f00fc4b3dea in EVP_PKEY_CTX_new (pkey=pkey@entry=0x559d90ba7950, e=e@entry=0x0) at pmeth_lib.c:272
#3 0x00007f00fc8007f7 in ssl3_send_client_verify (s=s@entry=0x7f00ec02db10) at s3_clnt.c:3258
#4 0x00007f00fc802be7 in ssl3_connect (s=0x7f00ec02db10) at s3_clnt.c:460
#5 0x00007f00fc80ce7e in ssl23_get_server_hello (s=0x7f00ec02db10) at s23_clnt.c:799
#6 ssl23_connect (s=0x7f00ec02db10) at s23_clnt.c:228
#7 0x00007f00fca640d8 in ssl_io_filter_handshake (filter_ctx=filter_ctx@entry=0x7f00ec0071c0) at ssl_engine_io.c:1086
5:
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=1, type=10, file=0x7f00fc5626fb "pmeth_lib.c", line=186) at cryptlib.c:601
#1 0x00007f00fc4b3c9d in int_ctx_new (pkey=pkey@entry=0x559d90ba7950, e=e@entry=0x0, id=<optimized out>, id@entry=-1)
at pmeth_lib.c:186
#2 0x00007f00fc4b3dea in EVP_PKEY_CTX_new (pkey=pkey@entry=0x559d90ba7950, e=e@entry=0x0) at pmeth_lib.c:272
#3 0x00007f00fc4ad969 in EVP_SignFinal (ctx=ctx@entry=0x7f00f92ef460,
sigret=sigret@entry=0x7f00ec030f78 "q\317\326\343\355\063i\376\265Q\360\222\360\222\n1\016\237)j\337\200\246ZZ^Q\274\t\302\063#\al\320@z\210\241\242k\t\355_s/\365\304T\225\206h\245\276P\325\235\373-J\026(U\004\b\f\003aaa1\f0\n\006\003U\004\n\f\003aaa1\f0\n\006\003U\004\v\f\003aaa1\v0\t\006\003U\004\003\f\002ca0\036\027\r190404004915Z\027\r290401004915Z0R1\v0\t\006\003U\004\006\023\002JP1\025\060\023\006\003U\004\a\f\fDefault City1\034\060\032\006\003U\004\n\f\023Default "..., siglen=siglen@entry=0x7f00f92ef450,
pkey=pkey@entry=0x559d90ba7950) at p_sign.c:98
#4 0x00007f00fc8008ec in ssl3_send_client_verify (s=s@entry=0x7f00ec02db10) at s3_clnt.c:3292
#5 0x00007f00fc802be7 in ssl3_connect (s=0x7f00ec02db10) at s3_clnt.c:460
#6 0x00007f00fc80ce7e in ssl23_get_server_hello (s=0x7f00ec02db10) at s23_clnt.c:799
#7 ssl23_connect (s=0x7f00ec02db10) at s23_clnt.c:228
#8 0x00007f00fca640d8 in ssl_io_filter_handshake (filter_ctx=filter_ctx@entry=0x7f00ec0071c0) at ssl_engine_io.c:1086
6:
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=-1, type=10, file=0x7f00fc569c8f "p_lib.c", line=391) at cryptlib.c:601
#1 0x00007f00fc4ae529 in EVP_PKEY_free (x=0x559d90ba7950) at p_lib.c:391
#2 0x00007f00fc4b3baa in EVP_PKEY_CTX_free (ctx=0x7f00ec00aa80) at pmeth_lib.c:343
#3 0x00007f00fc4ad8c8 in EVP_SignFinal (ctx=ctx@entry=0x7f00f92ef460,
sigret=sigret@entry=0x7f00ec030f78 "\242\272\002X\027\202\257\320\025\n\376\271u\f*\307\223nG\300\316 z\355(\226N\035\273B$i\\T\374\273\307\270\251\327G\210\232\070\334\061\200\351c\367\210\332jOIv1\232\374\006\002R\367g\264\067Vf:\037<2\314\361\301wF\a3s\356\003\356D\306\375\272\016\037\245\247`\350\371\365\305\025\237L\001\331\023\334\275\310\215\337\006A\306\005\366^\004i\327\335\243\222\006\252\250m\362\377G\222\314\"/z\036/&\330C\017\214\374\311\377\365\\\336ace\306\377}\324\316>\220\357\326\351v\230J\205\213\227\326f\224\317\363\243<\361\326\005d\"D\327*\221\277\254\266\323\201\232\272\321\016\320\004G\022\v\373o\250\017\037\027\067"...,
siglen=siglen@entry=0x7f00f92ef450, pkey=pkey@entry=0x559d90ba7950) at p_sign.c:126
#4 0x00007f00fc8008ec in ssl3_send_client_verify (s=s@entry=0x7f00ec02db10) at s3_clnt.c:3292
#5 0x00007f00fc802be7 in ssl3_connect (s=0x7f00ec02db10) at s3_clnt.c:460
#6 0x00007f00fc80ce7e in ssl23_get_server_hello (s=0x7f00ec02db10) at s23_clnt.c:799
#7 ssl23_connect (s=0x7f00ec02db10) at s23_clnt.c:228
#8 0x00007f00fca640d8 in ssl_io_filter_handshake (filter_ctx=filter_ctx@entry=0x7f00ec0071c0) at ssl_engine_io.c:1086
7:
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=-1, type=10, file=0x7f00fc569c8f "p_lib.c", line=391) at cryptlib.c:601
#1 0x00007f00fc4ae529 in EVP_PKEY_free (x=0x559d90ba7950) at p_lib.c:391
#2 0x00007f00fc4b3baa in EVP_PKEY_CTX_free (ctx=0x7f00ec013220) at pmeth_lib.c:343
#3 0x00007f00fc800788 in ssl3_send_client_verify (s=s@entry=0x7f00ec02db10) at s3_clnt.c:3364
#4 0x00007f00fc802be7 in ssl3_connect (s=0x7f00ec02db10) at s3_clnt.c:460
#5 0x00007f00fc80ce7e in ssl23_get_server_hello (s=0x7f00ec02db10) at s23_clnt.c:799
#6 ssl23_connect (s=0x7f00ec02db10) at s23_clnt.c:228
#7 0x00007f00fca640d8 in ssl_io_filter_handshake (filter_ctx=filter_ctx@entry=0x7f00ec0071c0) at ssl_engine_io.c:1086
8:
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=-1, type=10, file=0x7f00fc569c8f "p_lib.c", line=391) at cryptlib.c:601
#1 0x00007f00fc4ae529 in EVP_PKEY_free (x=0x559d90ba7950) at p_lib.c:391
#2 0x00007f00fc823cf4 in ssl_cert_clear_certs (c=c@entry=0x7f00ec022410) at ssl_cert.c:433
#3 0x00007f00fc8244aa in ssl_cert_free (c=0x7f00ec022410) at ssl_cert.c:485
#4 0x00007f00fc822cae in SSL_free (s=0x7f00ec02db10) at ssl_lib.c:620
#5 0x00007f00fca63e0e in ssl_filter_io_shutdown (c=c@entry=0x7f00ec006ba0, abortive=abortive@entry=1, filter_ctx=0x7f00ec0071c0)
at ssl_engine_io.c:1001
Please notice there are 7 occurrences with type=10 and 1 occurrence with type=5.
ssl_util_thr_lock in httpd-2.4.6/modules/ssl/ssl_util.c is as follows:
--------------------------------------------------------------
339 static void ssl_util_thr_lock(int mode, int type,
340 const char *file, int line)
341 {
342 if (type < lock_num_locks) {
343 if (mode & CRYPTO_LOCK) {
344 apr_thread_mutex_lock(lock_cs[type]);
345 }
346 else {
347 apr_thread_mutex_unlock(lock_cs[type]);
348 }
349 }
350 }
--------------------------------------------------------------
It shows that the mod_ssl provides the array of mutex(lock_cs) for each "type". Locking works for the same "type", otherwise not.
Therefore, if
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=1, type=5, file=0x7f00fca7a4b8 "ssl_engine_kernel.c", line=1571) at cryptlib.c:601
and
#0 CRYPTO_add_lock (pointer=0x559d90ba7958, amount=1, type=10, file=0x7f00fc836540 "ssl_rsa.c", line=232) at cryptlib.c:601
occur at the same time, the actual value of EVP_PKEY.references(pointer=0x559d90ba7958) may be smaller than the expected value under race condition.
ssl_callback_proxy_cert in httpd-2.4.6/modules/ssl/ssl_engine_kernel.c:1571 is:
--------------------------------------------------------------
1571 modssl_set_cert_info(info, x509, pkey);
--------------------------------------------------------------
and modssl_set_cert_info is defined as:
--------------------------------------------------------------
1510 #define modssl_set_cert_info(info, cert, pkey) \
1511 *cert = info->x509; \
1512 CRYPTO_add(&(*cert)->references, +1, CRYPTO_LOCK_X509); \
1513 *pkey = info->x_pkey->dec_pkey; \
1514 CRYPTO_add(&(*pkey)->references, +1, CRYPTO_LOCK_X509_PKEY)
--------------------------------------------------------------
Here CRYPTO_LOCK_X509_PKEY=5. It should be 10.
I will change the code tomorrow and confirm if it works.
Good work with the investigation! Yes, the CRYPTO_LOCK_EVP_PKEY should be used instead. So this is apparently bug in mod_ssl code. Tomas, Thanks! Here is a patch:
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index a088df1..e48f1d5 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -1578,7 +1578,7 @@ static void modssl_proxy_info_log(conn_rec *c,
*cert = info->x509; \
CRYPTO_add(&(*cert)->references, +1, CRYPTO_LOCK_X509); \
*pkey = info->x_pkey->dec_pkey; \
- CRYPTO_add(&(*pkey)->references, +1, CRYPTO_LOCK_X509_PKEY)
+ CRYPTO_add(&(*pkey)->references, +1, CRYPTO_LOCK_EVP_PKEY)
int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
{
I confirmed a single shot of `ab -n 100000 -c 8 http://localhost/foo/` creates >10 core files on my setup and creates 0 core file with this fix.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (httpd bug fix and enhancement update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2020:5033 |