diff options
author | Michael Brown | 2010-07-07 13:57:08 +0200 |
---|---|---|
committer | Michael Brown | 2010-07-07 13:57:08 +0200 |
commit | 68c2f07f159cda5735d0297a8b70a415788766d7 (patch) | |
tree | 20d4bb73b239ec4eb294480da732aaa4e2ff3784 /src/net/tcp.c | |
parent | [refcnt] Fix embedded image building (diff) | |
download | ipxe-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.c | 11 |
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 ); |