Re: Proposing amd64-hardened architecture for Debian
Hi Riku,
2014-04-19 13:26 GMT+02:00 Riku Voipio <riku.voipio@iki.fi>:
> On Tue, Apr 15, 2014 at 12:00:33PM +0200, Balint Reczey wrote:
>> Facing last week's Heartbleed [1] bug the need for improving the
>> security of our systems became more apparent than usually. In Debian
>> there are widely used methods for Hardening [2] packages at build time
>> and guidelines [3] for improving the default installations' security.
>
> Riding the Heartbleed publicity wave seems unwise, unless you can
> propose a hardening flag that would have protected users from
> Heartbleed. Else, Heartbleed merely serves on a example
> how wallpapering problems over with "hardened" binaries often
> doesn't help you at all..
>
> Considering that most issues protected by compiler hardening are
> also detectable by static/dynamic code analysis, a more effective security
> measure would be to spend time with clang static analyzer, valgrind, trinity
> and other tools... or actualy reviewing patches that security critical
> projects recieve.
Thank you for bringing this up now.
I have just managed to compile openssl, without the fix for the
Heartbleed test but with -fsanitize=address, and as I expected it
avoids leaking anything, I see only this in the Apache2's error.log:
...
[Sat Apr 19 13:44:58.818704 2014] [core:notice] [pid 18456:tid
3068020544] AH00094: Command line: '/us
r/sbin/apache2'
=================================================================
==18459==ERROR: AddressSanitizer: heap-buffer-overflow on address
0xb4960411 at pc 0xb547a785 bp 0xb14f7c88 sp 0xb14f7c7c
READ of size 1 at 0xb4960411 thread T2
ASAN:SIGSEGV
==18459==AddressSanitizer: while reporting a bug found another one.Ignoring.
=================================================================
==18461==ERROR: AddressSanitizer: heap-buffer-overflow on address
0xb4960411 at pc 0xb547a785 bp 0xaf86bc88 sp 0xaf86bc7c
READ of size 1 at 0xb4960411 thread T5
ASAN:SIGSEGV
==18461==AddressSanitizer: while reporting a bug found another one.Ignoring.
...
Since this is exactly the flag I looked at for amd64-hardened, if we
had this arch existing a few weeks ago it would have prevented
successful attacks on this platform.
I used Heartleech for triggering the bug and the attached debdiff on openssl.
The PoC is fragile because you need to set LD_PRELOAD=libasan1 and
compile the package with the following command:
CC=gcc-4.9 DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -rfakeroot -us -uc
I have also disabled OpenSSL's feelist implementation because any
custom memory handling would be disabled on amd64-hardened to let ASAN
work effectively.
During creating the PoC I have hit several bugs which I had to work
around in the patch:
Changes:
openssl (1.0.1f-1~dontuseheartbleedtest) UNRELEASED; urgency=low
.
* Enable -fsanitize=address
* Disable freelist using -DOPENSSL_NO_BUF_FREELISTS
* Add patch to fix freelist reuse from here:
http://www.tedunangst.com/flak/post/analysis-of-openssl-freelist-reuse
* CVE-2014-0160 a.k.a Heartbleed is not fixed in this version!
* Add patch 'Check i before r[i]' to fix buffer overflow by reading
* Export ssl3_write_bytes() for compiling Heartleech
* Use -DOPENSSL_NO_ASM to prevent crash in OPENSSL_cpuid_setup on i386
Cheers,
Balint
diff -Nru openssl-1.0.1f/debian/changelog openssl-1.0.1f/debian/changelog
--- openssl-1.0.1f/debian/changelog 2014-01-06 19:02:23.000000000 +0100
+++ openssl-1.0.1f/debian/changelog 2014-04-18 14:18:09.000000000 +0200
@@ -1,3 +1,16 @@
+openssl (1.0.1f-1~dontuseheartbleedtest) UNRELEASED; urgency=low
+
+ * Enable -fsanitize=address
+ * Disable freelist using -DOPENSSL_NO_BUF_FREELISTS
+ * Add patch to fix freelist reuse from here:
+ http://www.tedunangst.com/flak/post/analysis-of-openssl-freelist-reuse
+ * CVE-2014-0160 a.k.a Heartbleed is not fixed in this version!
+ * Add patch 'Check i before r[i]' to fix buffer overflow by reading
+ * Export ssl3_write_bytes() for compiling Heartleech
+ * Use -DOPENSSL_NO_ASM to prevent crash in OPENSSL_cpuid_setup on i386
+
+ -- Balint Reczey <rbalint@minipanda.sz13.dyndns.org> Thu, 17 Apr 2014 20:12:10 +0200
+
openssl (1.0.1f-1) unstable; urgency=high
* New upstream version
diff -Nru openssl-1.0.1f/debian/patches/0001-Check-i-before-r-i.patch openssl-1.0.1f/debian/patches/0001-Check-i-before-r-i.patch
--- openssl-1.0.1f/debian/patches/0001-Check-i-before-r-i.patch 1970-01-01 01:00:00.000000000 +0100
+++ openssl-1.0.1f/debian/patches/0001-Check-i-before-r-i.patch 2014-04-17 20:17:12.000000000 +0200
@@ -0,0 +1,33 @@
+From 73c92dfa0c15d7932d86130a525d1a1bc43c312a Mon Sep 17 00:00:00 2001
+From: "Dr. Stephen Henson" <steve@openssl.org>
+Date: Tue, 28 Jan 2014 15:10:27 +0000
+Subject: [PATCH] Check i before r[i].
+
+PR#3244
+(cherry picked from commit 9614d2c676ffe74ce0c919d9e5c0d622a011cbed)
+---
+ ssl/s3_srvr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: openssl-1.0.1f/ssl/s3_srvr.c
+===================================================================
+--- openssl-1.0.1f.orig/ssl/s3_srvr.c 2014-04-17 20:17:05.172900103 +0200
++++ openssl-1.0.1f/ssl/s3_srvr.c 2014-04-17 20:17:05.164900064 +0200
+@@ -1830,7 +1830,7 @@
+ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
+ goto f_err;
+ }
+- for (i=0; r[i] != NULL && i<4; i++)
++ for (i=0; i < 4 && r[i] != NULL; i++)
+ {
+ nr[i]=BN_num_bytes(r[i]);
+ #ifndef OPENSSL_NO_SRP
+@@ -1866,7 +1866,7 @@
+ d=(unsigned char *)s->init_buf->data;
+ p= &(d[4]);
+
+- for (i=0; r[i] != NULL && i<4; i++)
++ for (i=0; i < 4 && r[i] != NULL; i++)
+ {
+ #ifndef OPENSSL_NO_SRP
+ if ((i == 2) && (type & SSL_kSRP))
diff -Nru openssl-1.0.1f/debian/patches/export-ssl3_write_bytes-for-heartleech.patch openssl-1.0.1f/debian/patches/export-ssl3_write_bytes-for-heartleech.patch
--- openssl-1.0.1f/debian/patches/export-ssl3_write_bytes-for-heartleech.patch 1970-01-01 01:00:00.000000000 +0100
+++ openssl-1.0.1f/debian/patches/export-ssl3_write_bytes-for-heartleech.patch 2014-04-18 12:29:38.000000000 +0200
@@ -0,0 +1,17 @@
+Description: Export ssl3_write_bytes for Heartleech
+ Don't use this patch on a production system!
+ .
+Author: Balint Reczey <rbalint@minipanda.sz13.dyndns.org>
+
+Index: openssl-1.0.1f/openssl.ld
+===================================================================
+--- openssl-1.0.1f.orig/openssl.ld 2014-04-18 12:27:57.000000000 +0200
++++ openssl-1.0.1f/openssl.ld 2014-04-18 12:29:27.735498902 +0200
+@@ -4449,6 +4449,7 @@
+
+ OPENSSL_1.0.1 {
+ global:
++ ssl3_write_bytes;
+ SSL_renegotiate_abbreviated;
+ TLSv1_1_method;
+ TLSv1_1_client_method;
diff -Nru openssl-1.0.1f/debian/patches/fix-freelist.patch openssl-1.0.1f/debian/patches/fix-freelist.patch
--- openssl-1.0.1f/debian/patches/fix-freelist.patch 1970-01-01 01:00:00.000000000 +0100
+++ openssl-1.0.1f/debian/patches/fix-freelist.patch 2014-04-17 20:11:28.000000000 +0200
@@ -0,0 +1,19 @@
+From: http://ftp.openbsd.org/pub/OpenBSD/patches/5.5/common/004_openssl.patch.sig
+
+Index: lib/libssl/src/ssl/s3_pkt.c
+===================================================================
+RCS file: /cvs/src/lib/libssl/src/ssl/s3_pkt.c,v
+retrieving revision 1.20
+retrieving revision 1.20.4.1
+diff -u -p -u -r1.20 -r1.20.4.1
+--- ./ssl/s3_pkt.c 27 Feb 2014 21:04:57 -0000 1.20
++++ ./ssl/s3_pkt.c 12 Apr 2014 17:01:14 -0000 1.20.4.1
+@@ -1055,7 +1055,7 @@ start:
+ {
+ s->rstate=SSL_ST_READ_HEADER;
+ rr->off=0;
+- if (s->mode & SSL_MODE_RELEASE_BUFFERS)
++ if (s->mode & SSL_MODE_RELEASE_BUFFERS && s->s3->rbuf.left == 0)
+ ssl3_release_read_buffer(s);
+ }
+ }
diff -Nru openssl-1.0.1f/debian/patches/series openssl-1.0.1f/debian/patches/series
--- openssl-1.0.1f/debian/patches/series 2014-01-06 18:55:04.000000000 +0100
+++ openssl-1.0.1f/debian/patches/series 2014-04-18 12:16:09.000000000 +0200
@@ -32,3 +32,6 @@
openssl_fix_for_x32.patch
fix-pod-errors.patch
req_bits.patch
+fix-freelist.patch
+0001-Check-i-before-r-i.patch
+export-ssl3_write_bytes-for-heartleech.patch
diff -Nru openssl-1.0.1f/debian/rules openssl-1.0.1f/debian/rules
--- openssl-1.0.1f/debian/rules 2013-12-22 17:48:48.000000000 +0100
+++ openssl-1.0.1f/debian/rules 2014-04-18 22:37:13.000000000 +0200
@@ -20,7 +20,8 @@
DEB_HOST_MULTIARCH=$(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
DEB_HOST_ARCH_CPU=$(shell dpkg-architecture -qDEB_HOST_ARCH_CPU)
-CONFARGS = --prefix=/usr --openssldir=/usr/lib/ssl --libdir=lib/$(DEB_HOST_MULTIARCH) no-idea no-mdc2 no-rc5 no-zlib enable-tlsext no-ssl2
+# OPENSSL_NO_ASM to prevent segfault in OPENSSL_cpuid_setup
+CONFARGS = --prefix=/usr --openssldir=/usr/lib/ssl --libdir=lib/$(DEB_HOST_MULTIARCH) no-idea no-mdc3 no-rc5 no-zlib enable-tlsext no-ssl2 no-asm
OPT_alpha = ev4 ev5
OPT_i386 = i586 i686/cmov
ARCHOPTS = OPT_$(DEB_HOST_ARCH)
@@ -36,6 +37,10 @@
MAKE_TEST = :
endif
+export DEB_CPPFLAGS_APPEND=-DOPENSSL_NO_BUF_FREELIST -DOPENSSL_NO_ASM
+export DEB_CFLAGS_APPEND=-fsanitize=address
+export DEB_LDFLAGS_APPEND=-static-libasan
+
build: build-arch build-indep
build-arch: build-stamp
build-indep: build-stamp
Reply to: