summaryrefslogtreecommitdiffstats
path: root/src/net/tcp.c
diff options
context:
space:
mode:
authorMichael Brown2010-07-07 13:57:08 +0200
committerMichael Brown2010-07-07 13:57:08 +0200
commit68c2f07f159cda5735d0297a8b70a415788766d7 (patch)
tree20d4bb73b239ec4eb294480da732aaa4e2ff3784 /src/net/tcp.c
parent[refcnt] Fix embedded image building (diff)
downloadipxe-68c2f07f159cda5735d0297a8b70a415788766d7.tar.gz
ipxe-68c2f07f159cda5735d0297a8b70a415788766d7.tar.xz
ipxe-68c2f07f159cda5735d0297a8b70a415788766d7.zip
[tcp] Fix potential use-after-free when accessing timestamp option
Reported-by: Piotr JaroszyƄski <p.jaroszynski@gmail.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/tcp.c')
-rw-r--r--src/net/tcp.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/net/tcp.c b/src/net/tcp.c
index d64153f3..78e4ba76 100644
--- a/src/net/tcp.c
+++ b/src/net/tcp.c
@@ -900,6 +900,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
uint32_t seq;
uint32_t ack;
uint32_t win;
+ uint32_t ts_recent;
unsigned int flags;
size_t len;
int rc;
@@ -941,6 +942,8 @@ static int tcp_rx ( struct io_buffer *iobuf,
flags = tcphdr->flags;
tcp_rx_opts ( tcp, ( ( ( void * ) tcphdr ) + sizeof ( *tcphdr ) ),
( hlen - sizeof ( *tcphdr ) ), &options );
+ ts_recent = ( options.tsopt ?
+ ntohl ( options.tsopt->tsval ) : tcp->ts_recent );
iob_pull ( iobuf, hlen );
len = iob_len ( iobuf );
@@ -981,7 +984,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
}
/* Handle new data, if any */
- tcp_rx_data ( tcp, seq, iobuf );
+ tcp_rx_data ( tcp, seq, iob_disown ( iobuf ) );
seq += len;
/* Handle FIN, if present */
@@ -990,9 +993,9 @@ static int tcp_rx ( struct io_buffer *iobuf,
seq++;
}
- /* Update timestamp, if present and applicable */
- if ( ( seq == tcp->rcv_ack ) && options.tsopt )
- tcp->ts_recent = ntohl ( options.tsopt->tsval );
+ /* Update timestamp, if applicable */
+ if ( seq == tcp->rcv_ack )
+ tcp->ts_recent = ts_recent;
/* Dump out any state change as a result of the received packet */
tcp_dump_state ( tcp );