Heap overflow bug in OpenSSL
lists.grok.org.uk
lists.grok.org.uk
He wrote a minimal RSA signature verification implementation that we've used ever since. This is the eighth bug that it has saved us from in the last ten years.
Attack surface reduction works.
Note, other parts of OpenSSH are vulnerable - specifically private key loading. So, if you allow untrusted users to supply private keys to ssh, ssh-add or ssh-keygen running in a privileged context, then you should patch this bug ASAP.
Its designers added all sorts of ways to save a few bits here and there by creating optional special cases to be handled in the encoders and decoders.
This makes complicated code with lots of edge cases for bugs to hide in, Cisco SNMP implementations were notoriously savaged by this. Ironically, it also requires lots of branches which slow down modern processors more than just reading the bits.
Fortunately most uses of ASN.1 have died. SNMP and SSL are still using it. It's not 1984 anymore, let it die.
There is a trick to ASN.1/DER encoding that gets it down into the hundreds- of- lines- of- code range (you get the whole document in memory and serialize/unserialize it backwards). I once wrote a program that converted arbitrary ASN.1/DER/BER buffers into a shell script that regenerated the same. It's not as complicated as it looks, but it's idiosyncratic and you have to think about it a specific way.
That said: I agree, it should be scorched off the planet with fire.
BER is complicated, but no more complicated than rfc-822 style headers, which are also poorly parsed by ad-hoc parsers, and were a wide source of vulnerabilities.
The just published DoD EBTS 3.0 standard uses ITL-2011 and is also defined using XSD. But it too looks to an ASN.1 binary representation of its XML markup messages to get the data compression and performance needed for high volume transaction systems and hand held mobile biometric collection devices.
It was a really annoying war (I suspect there isn't any other kind although some people apparently really enjoy the standards 'game').
My favorite quote from Bob Lyon at the time, "Try to solve the problem, not the future."
https://twitter.com/#!/mdowd/status/192986878138523648
Here's the actual page: http://i.imgur.com/vPjOR.jpg
Firstly and most importantly: check http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/dev-... to see whether the Gentoo developers have already bumped OpenSSL in the official repository. If so, ignore everything below!
wget -O /usr/portage/distfiles/openssl-1.0.0i.tar.gz http://www.openssl.org/source/openssl-1.0.0i.tar.gz
chown portage:portage /usr/portage/distfiles/openssl-1.0.0i.tar.gz
chmod g+w /usr/portage/distfiles/openssl-1.0.0i.tar.gz
mkdir -p /usr/local/portage/dev-libs/openssl
cp /usr/portage/dev-libs/openssl/openssl-1.0.0h.ebuild /usr/local/portage/dev-libs/openssl/openssl-1.0.0i.ebuild
cp -R /usr/portage/dev-libs/openssl/files /usr/local/portage/dev-libs/openssl/
ebuild /usr/local/portage/dev-libs/openssl/openssl-1.0.0i.ebuild digest
emerge -1q =dev-libs/openssl-1.0.0i
shutdown -r -t 0 now
Skip the first 3 commands when mirrors have the latest OpenSSL tarballs.Preferably skip the last command and manually restart daemons that rely on OpenSSL. I have used the drastic example of restarting the entire server in case someone blindly follows the above commands without thinking it through carefully.
Note that openssl-1.0.1* is currently masked in Gentoo ~amd64. If you have it unmasked, it should be easy to adjust the above commands to use openssl-1.0.1a instead.
https://github.com/search?q=d2i_X509_bio&type=Code
http://www.koders.com/default.aspx?s=d2i_X509_bio
Examples of impacted software include Android, Apache HTTPd (mod_ssl)[1] and Ruby. To reiterate what you've already stated elsewhere in this discussion, software shouldn't have a need to call these functions to validate certificates provided by remote clients. Users of email clients making heavy use of S/MIME and administrators managing PKI (signing, revoking, etc) may need to apply caution.
[1] See line 99 at https://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/... where Apache tries to load a PEM formatted certificate. If this fails, Apache tries loading the file as a DER+Base64 formatted certificate or as a last resort, just DER (both which use the vulnerable d2i_X509_bio function). Given that the PEM format is the standard that most Apache administrators are using and injection of vulnerable certificates and keys usually requires root permissions, Apache/mod_ssl users can probably treat this vulnerability as a non-issue.
When Tavis Ormandy says "textbook heap overflow", patch fast.
It's mostly users of OpenSSL who are calling d2i_XXX_bio or d2i_XXX_fp.
php-5.4.1RC2 (and php-5.4.0): potentially affected (one match for d2i_PKCS12_bio)
tar -xjOf /usr/portage/distfiles/php-5.4.1RC2.tar.bz2 | grep d2i
nginx-1.1.19: probably safe (1 match for d2i_SSL_SESSION) tar -xzOf /usr/portage/distfiles/nginx-1.1.19.tar.gz | grep d2i
postgresql-9.1.3: probably safe (no matches) tar -xjOf /usr/portage/distfiles/postgresql-9.1.3.tar.bz2 | grep d2i
postfix-2.9.1: probably safe
(one match for X509_get_ext_d2i and d2i_SSL_SESSION each) tar -xzOf /usr/portage/distfiles/postfix-2.9.1.tar.gz | grep d2i
dovecot-2.1.4: probably safe (3 matches for d2i_DHparams, 1 match for X509_get_ext_d2i) tar -xzOf /usr/portage/distfiles/dovecot-2.1.4.tar.gz | grep d2iYou are probably not using the affected functions.
A hypothetical future Github feature that allowed users to upload SSL certs in lieu of SSH keys might have to review their code to make sure they weren't using OpenSSL BIOs to read certs from (or just patch).
You should patch anyways. From now on, professional security assessments are going to doc this version of OpenSSL as a vulnerability.
Good to know I've not got anything to worry about personally, though. You've explained it well.
wget -q -O - http://swupdate.openvpn.org/community/releases/openvpn-2.2.2... | tar -xzO | grep d2i
if ((eku = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i (x509, NID_ext_key_usage, NULL, NULL)) == NULL) {
if ((ku = (ASN1_BIT_STRING *)X509_get_ext_d2i (x509, NID_key_usage, NULL, NULL)) == NULL) {
p12 = d2i_PKCS12_bio(b64, NULL);
p12 = d2i_PKCS12_fp(fp, NULL);
cert = d2i_X509(NULL, (const unsigned char **) &cd->cert_context->pbCertEncoded,I think more importantly is whether it is likely to allow a server to be remotely exploited. The answer to that is "probably not", and "very likely not" if using OpenVPN's tls-auth option. At least as far as I understand the issue.
Also, http://article.gmane.org/gmane.network.openvpn.devel/6309
Always.
I'd even say they should always be uintmax_t in C.
Smart programming languages have bignum integers and seamless promotion between fixnum and bignum versions. Thus they avoid the issue completely, no stupid casts (especially casts which change both signedness and size), no overflows, no nothing, just an integer length.
It's a perfect world and everyone should try to achieve it.
C is not such programming language, with the closest approximation being uintmax_t.
size_t is of course enough in practice.
I know this decision (to simply wrap around in the case of an over/underflow) was probably performance-driven, but on the other hand, if the common languages had required it, CPUs would have better support for it...
Edit: Some googling shows that Microsoft has a SafeInt class in common use that reports under/overflow: http://safeint.codeplex.com/ . Still it feels like a kludge for this to be not part of the main language.
But a "trap on overflow" signed and unsigned int type would be nice.
Code of exactly that form in the patch for this bug made me do a double take. Fortunately, they'd also changed the a & b from plain ints to size_t, so it was ok.
That is not the issue here, though: casting longs to ints would cause trouble even if both are unsigned.
Consistent use of one (unsigned) type for lengths would avoid issues because there'd be no casts.
off_t is signed and doesn't make sense because file length can't be negative.
Wrong, it's used to seek in both directions in calls where direction is signed by... a sign!
off_t is wrong for maintaining length because off_t is signed and lengths are fundamentally unsigned.
Signed offset is OK for seeking.
(You don't need off64_t if you compile with the proper #defines, which you should do on Linux.)
size_t s = get_size();
int *a = (int *)malloc(s * sizeof(int));
for (size_t i=0; i<s; i++) {
a[i] = get_int();
}
I've gotten in the habit of, when reading array sizes over the wire, explicitly limiting to a reasonable value like 1 million. Occasionally things should be allowed to use all available memory, but it's rare.http://google-styleguide.googlecode.com/svn/trunk/cppguide.x...
I prefer this since unsigned underflow (which is an easy bug) produces a value which is still a valid size and is not detected by IOC or -ftrapv. Also, it requires you to use unsigned loop indexes, which will simply lead to more bugs.
The fact that your program contains no individual objects whose size is > INT_MAX should be a sign that you should use int for their size.