Skip to content

Commit 96db902

Browse files
committed
Add heartbeat extension bounds check.
A missing bounds check in the handling of the TLS heartbeat extension can be used to reveal up to 64k of memory to a connected client or server. Thanks for Neel Mehta of Google Security for discovering this bug and to Adam Langley <agl@chromium.org> and Bodo Moeller <bmoeller@acm.org> for preparing the fix (CVE-2014-0160)
1 parent 0d7717f commit 96db902

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

CHANGES

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55
Changes between 1.0.1f and 1.0.1g [xx XXX xxxx]
66

7+
*) A missing bounds check in the handling of the TLS heartbeat extension
8+
can be used to reveal up to 64k of memory to a connected client or
9+
server.
10+
11+
Thanks for Neel Mehta of Google Security for discovering this bug and to
12+
Adam Langley <agl@chromium.org> and Bodo Moeller <bmoeller@acm.org> for
13+
preparing the fix (CVE-2014-0160)
14+
[Adam Langley, Bodo Moeller]
15+
716
*) Fix for the attack described in the paper "Recovering OpenSSL
817
ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack"
918
by Yuval Yarom and Naomi Benger. Details can be obtained from:

ssl/d1_both.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,26 +1459,36 @@ dtls1_process_heartbeat(SSL *s)
14591459
unsigned int payload;
14601460
unsigned int padding = 16; /* Use minimum padding */
14611461

1462-
/* Read type and payload length first */
1463-
hbtype = *p++;
1464-
n2s(p, payload);
1465-
pl = p;
1466-
14671462
if (s->msg_callback)
14681463
s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
14691464
&s->s3->rrec.data[0], s->s3->rrec.length,
14701465
s, s->msg_callback_arg);
14711466

1467+
/* Read type and payload length first */
1468+
if (1 + 2 + 16 > s->s3->rrec.length)
1469+
return 0; /* silently discard */
1470+
hbtype = *p++;
1471+
n2s(p, payload);
1472+
if (1 + 2 + payload + 16 > s->s3->rrec.length)
1473+
return 0; /* silently discard per RFC 6520 sec. 4 */
1474+
pl = p;
1475+
14721476
if (hbtype == TLS1_HB_REQUEST)
14731477
{
14741478
unsigned char *buffer, *bp;
1479+
unsigned int write_length = 1 /* heartbeat type */ +
1480+
2 /* heartbeat length */ +
1481+
payload + padding;
14751482
int r;
14761483

1484+
if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
1485+
return 0;
1486+
14771487
/* Allocate memory for the response, size is 1 byte
14781488
* message type, plus 2 bytes payload length, plus
14791489
* payload, plus padding
14801490
*/
1481-
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
1491+
buffer = OPENSSL_malloc(write_length);
14821492
bp = buffer;
14831493

14841494
/* Enter response type, length and copy payload */
@@ -1489,11 +1499,11 @@ dtls1_process_heartbeat(SSL *s)
14891499
/* Random padding */
14901500
RAND_pseudo_bytes(bp, padding);
14911501

1492-
r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
1502+
r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
14931503

14941504
if (r >= 0 && s->msg_callback)
14951505
s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
1496-
buffer, 3 + payload + padding,
1506+
buffer, write_length,
14971507
s, s->msg_callback_arg);
14981508

14991509
OPENSSL_free(buffer);

ssl/t1_lib.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,16 +2588,20 @@ tls1_process_heartbeat(SSL *s)
25882588
unsigned int payload;
25892589
unsigned int padding = 16; /* Use minimum padding */
25902590

2591-
/* Read type and payload length first */
2592-
hbtype = *p++;
2593-
n2s(p, payload);
2594-
pl = p;
2595-
25962591
if (s->msg_callback)
25972592
s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
25982593
&s->s3->rrec.data[0], s->s3->rrec.length,
25992594
s, s->msg_callback_arg);
26002595

2596+
/* Read type and payload length first */
2597+
if (1 + 2 + 16 > s->s3->rrec.length)
2598+
return 0; /* silently discard */
2599+
hbtype = *p++;
2600+
n2s(p, payload);
2601+
if (1 + 2 + payload + 16 > s->s3->rrec.length)
2602+
return 0; /* silently discard per RFC 6520 sec. 4 */
2603+
pl = p;
2604+
26012605
if (hbtype == TLS1_HB_REQUEST)
26022606
{
26032607
unsigned char *buffer, *bp;

0 commit comments

Comments
 (0)