David Coppa <dco...@gmail.com> writes: > On Wed, 03 Aug 2016, Stuart Henderson wrote: > >> On 2016/08/03 12:10, Stuart Henderson wrote: >> > On 2016/07/30 17:04, Giovanni Bechis wrote: >> > > On Sat, Jul 30, 2016 at 11:57:14AM +0100, Stuart Henderson wrote: >> > > > Forwarding from an offlist message because incoming mail is broken.. >> > > > >> > > no problem for me, just renewed my certificate with >> > > authenticator=standalone @i386 (OpenBSD 6.0 (GENERIC) #1915: Tue Jul 26 >> > > 09:46:01 MDT 2016) >> > > Have you added wxallowed in fstab(5) ? >> > >> > So wxallowed is required for this; it turns out that this is >> > due to devel/py-cffi. py-cffi does an mmap which is currently >> > RWX unless it detects PaX on Linux in which case it changes >> > it to RW. But if I change things to permit that, we run into >> > another problem: the library using py-cffi in this case is >> > py-cryptography, which calls out to libcrypto, and it segfaults >> > after doing so: >> > >> > (gdb) bt >> > #0 0x000003d6f2169fc0 in ?? () >> > #1 0x000003d6bef3ba4c in internal_verify (ctx=0x7f7ffffe4eb0) >> > at >> > /usr/src/lib/libcrypto/crypto/../../libssl/src/crypto/x509/x509_vfy.c:1611 >> > #2 0x000003d6bef3d109 in X509_verify_cert (ctx=0x7f7ffffe4eb0) >> > at >> > /usr/src/lib/libcrypto/crypto/../../libssl/src/crypto/x509/x509_vfy.c:374 >> > #3 0x000003d78b79c8f0 in ssl_verify_cert_chain (s=0x3d6c5708000, >> > sk=Variable "sk" is not available. >> > ) >> > at /usr/src/lib/libssl/ssl/../../libssl/src/ssl/ssl_cert.c:448 >> > #4 0x000003d78b78c030 in ssl3_get_server_certificate (s=0x3d6c5708000) >> > at /usr/src/lib/libssl/ssl/../../libssl/src/ssl/s3_clnt.c:1015 >> > #5 0x000003d78b78d421 in ssl3_connect (s=0x3d6c5708000) >> > at /usr/src/lib/libssl/ssl/../../libssl/src/ssl/s3_clnt.c:297 >> > #6 0x000003d78b794c4e in ssl23_connect (s=0x3d6c5708000) >> > at /usr/src/lib/libssl/ssl/../../libssl/src/ssl/s23_clnt.c:477 >> > #7 0x000003d78a76f08c in _cffi_f_SSL_do_handshake () >> > from >> > /usr/local/lib/python2.7/site-packages/cryptography/hazmat/bindings/_openssl.so >> > #8 0x000003d70659d528 in PyEval_EvalFrameEx () >> > from /usr/local/lib/libpython2.7.so.0.0 >> > #9 0x000003d70659d2ea in PyEval_EvalFrameEx () >> > from /usr/local/lib/libpython2.7.so.0.0 >> > #10 0x000003d70659f33d in PyEval_EvalCodeEx () >> > >> > 1604 ok = x509_check_cert_time(ctx, xs, 0); >> > 1605 if (!ok) >> > 1606 goto end; >> > 1607 >> > 1608 /* The last error (if any) is still in the error >> > value */ >> > 1609 ctx->current_issuer = xi; >> > 1610 ctx->current_cert = xs; >> > 1611 ok = (*cb)(1, ctx); >> > 1612 if (!ok) >> > 1613 goto end; >> > >> > At the moment I don't have any ideas other than "mark /usr/local >> > as wxallowed if you want to run things using py-cffi". Can anyone >> > think of something better? >> > >> >> Here are some more prints from another run of this (this segfault >> is occurring with py-cffi patched to just do RW mappings; it occurs >> whether or not the partition is marked wxallowed). >> >> I can't do any more digging until next week. >> >> (gdb) bt >> #0 0x00001207405f1fc0 in ?? () >> #1 0x00001206b3377a4c in internal_verify (ctx=0x7f7ffffeaae0) >> at >> /usr/src/lib/libcrypto/crypto/../../libssl/src/crypto/x509/x509_vfy.c:1611 >> #2 0x00001206b3379109 in X509_verify_cert (ctx=0x7f7ffffeaae0) >> at >> /usr/src/lib/libcrypto/crypto/../../libssl/src/crypto/x509/x509_vfy.c:374 >> #3 0x00001206d2eff8f0 in ssl_verify_cert_chain (s=0x120700f1c000, >> sk=Variable "sk" is not available. >> ) >> at /usr/src/lib/libssl/ssl/../../libssl/src/ssl/ssl_cert.c:448 >> #4 0x00001206d2eef030 in ssl3_get_server_certificate (s=0x120700f1c000) >> at /usr/src/lib/libssl/ssl/../../libssl/src/ssl/s3_clnt.c:1015 >> #5 0x00001206d2ef0421 in ssl3_connect (s=0x120700f1c000) >> at /usr/src/lib/libssl/ssl/../../libssl/src/ssl/s3_clnt.c:297 >> #6 0x00001206d2ef7c4e in ssl23_connect (s=0x120700f1c000) >> at /usr/src/lib/libssl/ssl/../../libssl/src/ssl/s23_clnt.c:477 >> #7 0x00001206dca5a44f in _cffi_f_SSL_do_handshake (self=0x1206c2cf7dc0, >> arg0=0x1206b5421650) >> at >> /usr/obj/ports/py-cryptography-1.4/cryptography-1.4/temp.openbsd-6.0-amd64-2.7/_openssl.c:51236 >> #8 0x0000120731c1a528 in PyEval_EvalFrameEx () from >> /usr/local/lib/libpython2.7.so.0.0 >> #9 0x0000120731c1a2ea in PyEval_EvalFrameEx () from >> /usr/local/lib/libpython2.7.so.0.0 >> [..] >> #38 0x0000120731c1c33d in PyEval_EvalCodeEx () from >> /usr/local/lib/libpython2.7.so.0.0 >> #39 0x0000120731ba3bf7 in function_call () from >> /usr/local/lib/libpython2.7.so.0.0 >> #40 0x0000120731b79cc8 in PyObject_Call () from >> /usr/local/lib/libpython2.7.so.0.0 >> #41 0x0000120731b88f92 in instancemethod_call () from >> /usr/local/lib/libpython2.7.so.0.0 >> [..] >> (gdb) frame 1 >> #1 0x00001206b3377a4c in internal_verify (ctx=0x7f7ffffeaae0) >> at >> /usr/src/lib/libcrypto/crypto/../../libssl/src/crypto/x509/x509_vfy.c:1611 >> 1611 ok = (*cb)(1, ctx); >> (gdb) p *ctx >> $1 = {ctx = 0x1206c17c4d00, current_method = 0, cert = 0x12067c8ab600, >> untrusted = 0x1206c17ca8c0, crls = 0x0, >> param = 0x120753e79540, other_ctx = 0x0, verify = 0x1206b3377940 >> <internal_verify>, verify_cb = 0x1207405f1fc0, >> get_issuer = 0x1206b333f890 <X509_STORE_CTX_get1_issuer>, check_issued = >> 0x1206b3377240 <check_issued>, >> check_revocation = 0x1206b3378490 <check_revocation>, get_crl = 0, >> check_crl = 0x1206b3379220 <check_crl>, >> cert_crl = 0x1206b3377070 <cert_crl>, check_policy = 0x1206b3376f10 >> <check_policy>, >> lookup_certs = 0x1206b333fd10 <X509_STORE_get1_certs>, lookup_crls = >> 0x1206b333fb10 <X509_STORE_get1_crls>, >> cleanup = 0, valid = 0, last_untrusted = 3, chain = 0x1206a6a5c860, tree = >> 0x0, explicit_policy = 0, >> error_depth = 3, error = 0, current_cert = 0x1206d841ae00, current_issuer >> = 0x1206d841ae00, current_crl = 0x0, >> current_crl_score = 0, current_reasons = 0, parent = 0x0, ex_data = {sk = >> 0x1206a6a5ca00}} >> (gdb) list >> 1606 goto end; >> 1607 >> 1608 /* The last error (if any) is still in the error value >> */ >> 1609 ctx->current_issuer = xi; >> 1610 ctx->current_cert = xs; >> 1611 ok = (*cb)(1, ctx); >> 1612 if (!ok) >> 1613 goto end; >> 1614 >> 1615 n--; >> (gdb) p *ctx->cert >> $2 = {cert_info = 0x120738043f80, sig_alg = 0x1206fd9518f0, signature = >> 0x1206881396c0, valid = 0, references = 2, >> name = 0x1206de46cc00 "/CN=*.api.letsencrypt.org/O=INTERNET SECURITY >> RESEARCH GROUP/L=Mountain View/ST=California/C=US", ex_data = {sk = 0x0}, >> ex_pathlen = -1, ex_pcpathlen = 0, ex_flags = 262, ex_kusage = 160, >> ex_xkusage = 3, >> ex_nscert = 0, skid = 0x1206a6a5cd20, akid = 0x120699a98880, policy_cache >> = 0x0, crldp = 0x12068875b3a0, >> altname = 0x12068875b0a0, nc = 0x0, sha1_hash = >> "?[i?\205@???\a?O?\v??1B\022?", aux = 0x0} >> (gdb) p cb >> $3 = (int (*)(int, X509_STORE_CTX *)) 0x1207405f1fc0 >> >> So it's trying to call 0x1207405f1fc0 which is the function pointer >> stored in verify_cb. > > The problem is in py-openssl, which is still using dynamic ffi > callbacks, causing W^X violations. > > The diff below (adapted from an unmerged branch of py-cffi) makes > letsencrypt work for me.
Looks fine to me and works fine on i386, ok jca@ > https://bitbucket.org/cffi/cffi/issues/231/writeable-memory-execution-execmem-with > > https://github.com/pyca/cryptography/issues/2477 > > https://bugzilla.redhat.com/show_bug.cgi?id=1249685 > > Ciao! > David > > P.S.: I know this implementation has problems wrt fork() > (https://bugs.python.org/issue25653), but given that we already > took this road with devel/libffi rev 1.35... > The example code from https://bugzilla.redhat.com/show_bug.cgi?id=531233 > is already crashing for us. :( -- jca | PGP: 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE