Skip to content

Commit 7e84016

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) (cherry picked from commit 96db902)
1 parent a489632 commit 7e84016

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

CHANGES

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55
Changes between 1.0.1f and 1.0.2 [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

+18-8
Original file line numberDiff line numberDiff line change
@@ -1330,26 +1330,36 @@ dtls1_process_heartbeat(SSL *s)
13301330
unsigned int payload;
13311331
unsigned int padding = 16; /* Use minimum padding */
13321332

1333-
/* Read type and payload length first */
1334-
hbtype = *p++;
1335-
n2s(p, payload);
1336-
pl = p;
1337-
13381333
if (s->msg_callback)
13391334
s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
13401335
&s->s3->rrec.data[0], s->s3->rrec.length,
13411336
s, s->msg_callback_arg);
13421337

1338+
/* Read type and payload length first */
1339+
if (1 + 2 + 16 > s->s3->rrec.length)
1340+
return 0; /* silently discard */
1341+
hbtype = *p++;
1342+
n2s(p, payload);
1343+
if (1 + 2 + payload + 16 > s->s3->rrec.length)
1344+
return 0; /* silently discard per RFC 6520 sec. 4 */
1345+
pl = p;
1346+
13431347
if (hbtype == TLS1_HB_REQUEST)
13441348
{
13451349
unsigned char *buffer, *bp;
1350+
unsigned int write_length = 1 /* heartbeat type */ +
1351+
2 /* heartbeat length */ +
1352+
payload + padding;
13461353
int r;
13471354

1355+
if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
1356+
return 0;
1357+
13481358
/* Allocate memory for the response, size is 1 byte
13491359
* message type, plus 2 bytes payload length, plus
13501360
* payload, plus padding
13511361
*/
1352-
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
1362+
buffer = OPENSSL_malloc(write_length);
13531363
bp = buffer;
13541364

13551365
/* Enter response type, length and copy payload */
@@ -1360,11 +1370,11 @@ dtls1_process_heartbeat(SSL *s)
13601370
/* Random padding */
13611371
RAND_pseudo_bytes(bp, padding);
13621372

1363-
r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
1373+
r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
13641374

13651375
if (r >= 0 && s->msg_callback)
13661376
s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
1367-
buffer, 3 + payload + padding,
1377+
buffer, write_length,
13681378
s, s->msg_callback_arg);
13691379

13701380
OPENSSL_free(buffer);

ssl/t1_lib.c

+9-5
Original file line numberDiff line numberDiff line change
@@ -3801,16 +3801,20 @@ tls1_process_heartbeat(SSL *s)
38013801
unsigned int payload;
38023802
unsigned int padding = 16; /* Use minimum padding */
38033803

3804-
/* Read type and payload length first */
3805-
hbtype = *p++;
3806-
n2s(p, payload);
3807-
pl = p;
3808-
38093804
if (s->msg_callback)
38103805
s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
38113806
&s->s3->rrec.data[0], s->s3->rrec.length,
38123807
s, s->msg_callback_arg);
38133808

3809+
/* Read type and payload length first */
3810+
if (1 + 2 + 16 > s->s3->rrec.length)
3811+
return 0; /* silently discard */
3812+
hbtype = *p++;
3813+
n2s(p, payload);
3814+
if (1 + 2 + payload + 16 > s->s3->rrec.length)
3815+
return 0; /* silently discard per RFC 6520 sec. 4 */
3816+
pl = p;
3817+
38143818
if (hbtype == TLS1_HB_REQUEST)
38153819
{
38163820
unsigned char *buffer, *bp;

0 commit comments

Comments
 (0)