[radvd-devel-l] radvd crash with multiple interfaces when 1 interface comes back up
Pekka Savola
pekkas at netcore.fi
Tue May 4 05:20:31 EDT 2010
Hello,
During today's testing I found a similar problem that Teemu fixes last
year.
When you have multiple interfaces (IgnoreIfMissing=on, and one
interface is down, when you bring it back up, radvd crashes with a
segfault in timer.c:152 ("tm->prev->next = tm->next;").
Interestingly enough, I don't see this happening when running radvd as
root.
I played around with this a bit, but could not figure out the real
root cause. I'm tempted to work around this by applying the following
work-around fix. Anyone else interested in looking into this a bit
more?
On Thu, 27 Aug 2009, Teemu Torma wrote:
> On Thursday 27 August 2009 15:20:23 Pekka Savola wrote:
>> Anyone interested and have time to look at this? I'll try to figure
>> out more when I have a bit more time.
>
> I did that yesterday and I have been running the radvd with attached patch
> which seems to cure the problem.
>
> The issue is that when interface comes back up, send_ra will call
> reload_config which will reset timers for all interfaces. However, the
> current timer event will continue processing as usual and at the end will
> reset the current timer. Since reload_config already did that, timer list
> pointers will be screwed and at least in my case cause an infinite loop.
>
> I haven't tried this, but it might suffice to ignore already existing timer
> entry in set_timer (i.e, tm->next && tm->prev).
>
> I don't know the code well enough to say if this is a good way to deal with
> the issue.
>
> Teemu
-------------- next part --------------
Index: timer.c
===================================================================
RCS file: /work/cvsroot/radvd/timer.c,v
retrieving revision 1.9
diff -u -r1.9 timer.c
--- timer.c 18 Oct 2005 19:17:29 -0000 1.9
+++ timer.c 4 May 2010 09:14:52 -0000
@@ -147,7 +147,7 @@
*/
/* unused timers are initialized to LONG_MAX so we skip them */
- while (tm->expires.tv_sec != LONG_MAX && check_time_diff(tm, tv))
+ while (tm->next && tm->prev && tm->expires.tv_sec != LONG_MAX && check_time_diff(tm, tv))
{
tm->prev->next = tm->next;
tm->next->prev = tm->prev;
Index: CHANGES
===================================================================
RCS file: /work/cvsroot/radvd/CHANGES,v
retrieving revision 1.98
diff -u -r1.98 CHANGES
--- CHANGES 10 Mar 2010 07:57:36 -0000 1.98
+++ CHANGES 4 May 2010 09:14:52 -0000
@@ -1,5 +1,8 @@
$Id: CHANGES,v 1.98 2010/03/10 07:57:36 psavola Exp $
+04/05/2010 Fix a segmentation fault on reload_config() timer list
+ corruption that only occurs with multiple interfaces.
+
10/03/2010 Fix radvd skipping multiple interfaces when
UnicastOnly is on or AdvSendAdvert is off.
This got broken in radvd 1.3. Patch from Cedric BAIL.
More information about the radvd-devel-l
mailing list