Hello.
Let me return to thread, discussed a month ago, when 4.95-RC2 was released.
Upgrading from 4.94-2 to 4.95-RC2 I got numerous segfaults on sender verify
callout, in _gnutls_trust_list_get_issuer() from libgnutls30 library,
and had to roll back to 4.92. The last mail on topic was from Jeremy:
On Wed, Sep 08, 2021 at 09:50:54AM +0100, Jeremy Harris via Exim-users wrote:
> On 08/09/2021 07:58, Evgeniy Berdnikov via Exim-users wrote:
[...]
> > Fault happens on sender verify callout, in rcpt or pre-data ACLs.
> > Here is the recent example, callout from acl_check_rcpt:
> >
> > Reading symbols from /usr/sbin/exim4...
> > [New LWP 1352271]
> > [Thread debugging using libthread_db enabled]
> > Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
> > Core was generated by `/usr/sbin/exim4 -bd -q1m'.
> > Program terminated with signal SIGSEGV, Segmentation fault.
> > #0 0xf7238b0d in _gnutls_trust_list_get_issuer (list=0x58441780,
> > cert=0x59027530, issuer=0xffbec6a8, flags=0)
> > at ../../../lib/x509/verify-high.c:1026
>
> Looking at a current GnuTLS tree, hopefully not too different to
> that used for your library version:
>
> 1012 int _gnutls_trust_list_get_issuer(gnutls_x509_trust_list_t list,
> 1013 gnutls_x509_crt_t cert,
> 1014 gnutls_x509_crt_t * issuer,
> 1015 unsigned int flags)
> 1016 {
> 1017 int ret;
> 1018 unsigned int i;
> 1019 size_t hash;
> 1020
> 1021 hash =
> 1022 hash_pjw_bare(cert->raw_issuer_dn.data,
> 1023 cert->raw_issuer_dn.size);
> 1024 hash %= list->size;
> 1025
> 1026 for (i = 0; i < list->node[hash].trusted_ca_size; i++) {
> 1027 ret =
> 1028 gnutls_x509_crt_check_issuer(cert,
> 1029 list->node[hash].
> 1030 trusted_cas[i]);
>
> ... I'd say this is likely a problem internal to GnuTLS, not directly
> down to something exim passed it. You should involve the GnuTLS maintainers
> at this point (but please keep me in the loop).
Recently Exim-4.95 become available for Debian/testing, and I tried it,
keeping versions of packages libgnutls30 and libgnutls-dane0 (3.7.2-2).
The difference is impressive: for 4.94-2 there were no segfaults,
for 4.95-RC2 I got 134 core files in two days, for 4.95 I got only
one (!) core in two days. Segfault was in the same function.
But accidentally I catched that "list" in last core file is pointed not
to "struct gnutls_x509_trust_list_st", but to legal text string:
#0 0xf7291b0d in _gnutls_trust_list_get_issuer (list=0x57c945f0, cert=0x57c9f2b0, issuer=0xffb0b3c8, flags=0)
at ../../../lib/x509/verify-high.c:1026
1026 ../../../lib/x509/verify-high.c: No such file or directory.
(gdb) p list
$1 = (gnutls_x509_trust_list_t) 0x57c945f0
(gdb) x/s list
0x57c945f0: "validity"
(gdb)
Search for "validity" in binary files and sources of Exim and GnuTLS
shows that only one such string is in GnuTLS: lib/pkix_asn1_tab.c.
I studied previous 134 core files from 4.95-RC2, in most cases
"list" pointed to string, which is mentioned in lib/pkix_asn1_tab.c.
In particular, those strings pointed by "list" after crash
"algorithm" "notBefore" "serialNumber" "rdnSequence" "tbsCertificate"
"utcTime" "?1"
are present in GnuTLS sources and are absent in Exim source code.
I also looked through arguments of upper libgnutls30 entry point
before segfault: gnutls_certificate_verify_peers2(session,status).
The "session" is a huge structure, but it does not look as corrupted:
some well-named elements have reasonable values. So Jeremy's suggestion
that problem is in GnuTLS library looks reasonable.
One additional notice. I counted numbers of those specific for libgnutls
strings in last core file:
# for s in "validity" "algorithm" "notBefore" "serialNumber" "rdnSequence" "tbsCertificate" "utcTime" ; do echo -n "$s: " ; strings core.1400692 | grep -c "^$s\$" ; done
validity: 634
algorithm: 3661
notBefore: 633
serialNumber: 524
rdnSequence: 1269
tbsCertificate: 518
utcTime: 1019
High multiplication of memory structures looks strange, notably they are
rarely used ASN1 names... It may be indication of memory leakage, IMHO.
Any other ideas, what else can be inspected with this coredump?
--
Eugene Berdnikov