summaryrefslogtreecommitdiffstats
path: root/src/net/retry.c
diff options
context:
space:
mode:
authorMichael Brown2011-07-16 02:46:12 +0200
committerMichael Brown2011-07-16 02:49:47 +0200
commit17f09dfe03a8c6b46d30844d3cee28266b6971fe (patch)
tree519f0c558d7e5dc4a2387fcc16ab3d7c6405b7d1 /src/net/retry.c
parent[ipv4] Use broadcast link-layer address for all broadcast IPv4 addresses (diff)
downloadipxe-17f09dfe03a8c6b46d30844d3cee28266b6971fe.tar.gz
ipxe-17f09dfe03a8c6b46d30844d3cee28266b6971fe.tar.xz
ipxe-17f09dfe03a8c6b46d30844d3cee28266b6971fe.zip
[retry] Fix potential use-after-free in timer_expired()
timer->refcnt is allowed to be NULL, in which case the timer's expired() method may end up freeing the timer object. Discovered using valgrind. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/retry.c')
-rw-r--r--src/net/retry.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/net/retry.c b/src/net/retry.c
index 0aa165ab..7e20f0c8 100644
--- a/src/net/retry.c
+++ b/src/net/retry.c
@@ -148,6 +148,7 @@ void stop_timer ( struct retry_timer *timer ) {
* @v timer Retry timer
*/
static void timer_expired ( struct retry_timer *timer ) {
+ struct refcnt *refcnt = timer->refcnt;
int fail;
/* Stop timer without performing RTT calculations */
@@ -169,8 +170,9 @@ static void timer_expired ( struct retry_timer *timer ) {
/* Call expiry callback */
timer->expired ( timer, fail );
+ /* If refcnt is NULL, then timer may already have been freed */
- ref_put ( timer->refcnt );
+ ref_put ( refcnt );
}
/**