diff options
author | Till Straumann <strauman@slac.stanford.edu> | 2009-08-06 19:41:57 +0000 |
---|---|---|
committer | Till Straumann <strauman@slac.stanford.edu> | 2009-08-06 19:41:57 +0000 |
commit | d8b6f64e29c55a857ca346bd2247cd5aeddaab9e (patch) | |
tree | 161588d8f836ace7d7ccef74c8c616cf2319efe3 | |
parent | 2009-08-05 Till Straumann <Till.Straumann@TU-Berlin.de> (diff) | |
download | libbsdport-d8b6f64e29c55a857ca346bd2247cd5aeddaab9e.tar.bz2 |
2009-08-06 Till Straumann <Till.Straumann@TU-Berlin.de>
* libbsdport/rtems_callout.c: fixed possible race
condition. callout_stop() must check again from
critical/protected section of code if callout is still on
the list/active. Otherwise, the callout-task could
have executed and removed the callout between
callout_stop() checking the p_prev pointer and
entering the critical section.
-rw-r--r-- | bsd_eth_drivers/ChangeLog | 10 | ||||
-rw-r--r-- | bsd_eth_drivers/libbsdport/rtems_callout.c | 5 |
2 files changed, 15 insertions, 0 deletions
diff --git a/bsd_eth_drivers/ChangeLog b/bsd_eth_drivers/ChangeLog index 18bfe6f..dc67e4e 100644 --- a/bsd_eth_drivers/ChangeLog +++ b/bsd_eth_drivers/ChangeLog @@ -1,3 +1,13 @@ +2009-08-06 Till Straumann <Till.Straumann@TU-Berlin.de> + + * libbsdport/rtems_callout.c: fixed possible race + condition. callout_stop() must check again from + critical/protected section of code if callout is still on + the list/active. Otherwise, the callout-task could + have executed and removed the callout between + callout_stop() checking the p_prev pointer and + entering the critical section. + 2009-08-05 Till Straumann <Till.Straumann@TU-Berlin.de> * if_em/Makefile.am, if_em/e1000_osdep.h, if_em/if_em.c: diff --git a/bsd_eth_drivers/libbsdport/rtems_callout.c b/bsd_eth_drivers/libbsdport/rtems_callout.c index de1df83..c041c5b 100644 --- a/bsd_eth_drivers/libbsdport/rtems_callout.c +++ b/bsd_eth_drivers/libbsdport/rtems_callout.c @@ -186,6 +186,11 @@ LIST_KEY_DECL(k); return 0; /* not currently on a list */ LIST_LOCK(k); + /* have to check again */ + if ( ! c->c_pprev ) { + LIST_UNLOCK(k); + return 0; + } /* remove from list */ c_deq(c); rtems_interrupt_disable(l); |