Comments (6)
It's a use-after-free issue for a list traversal in age_routes():
-
age_routes() loops over this:
Lines 671 to 674 in 26c54d4
-
And inside this loop, this is called:
Lines 1190 to 1194 in 26c54d4
-
delete_mrtentry()
then callsdelete_grpentry()
(1st call) which then callsdelete_rp_grp_entry()
-
delete_rp_grp_entry()
thenfree()
's therp_grp_entry_ptr
we are currently using in the loop:
Line 768 in 26c54d4
-
Before the
delete_mrtentry()
callrp_grp_entry_ptr->rp_grp_next
was NULL. However after the free() it contains other, random values (when things crash).
from pim6sd.
Ouch, good catch! The code path in age_routes()
is hariy, to say the least! Interestingly enough pimd doesn't contain any embedded-RP code, so this is something that must have been added by the pim6sd team.
There is an age_misc()
as well, which also calls delete_rp_grp_entry()
, so it's possible the code in delete_grpentry()
is not needed if the rp_grp entry is cleaned up in a second pass, which is safer anyway.
from pim6sd.
Btw. valgrind also shows the use-after-free quite nicely, including the details where it was malloc'd, free'd and accessed:
$ valgrind --track-origins=yes /home/linus/dev-priv/pim6sd/src/pim6sd -d pim_bootstrap,pim_join_prune -n -f /tmp/pimtest/router2.conf
[...]
04:20:42.949 warning - setsockopt MRT6_DEL_MFC: No such file or directory
==2722== Invalid read of size 8
==2722== at 0x1271A9: age_routes (timer.c:673)
==2722== by 0x11492D: timer (main.c:577)
==2722== by 0x10AF09: age_callout_queue (callout.c:130)
==2722== by 0x10AA55: main (main.c:523)
==2722== Address 0x4a95240 is 0 bytes inside a block of size 64 free'd
==2722== at 0x48369AB: free (vg_replace_malloc.c:530)
==2722== by 0x119F9B: delete_grpentry (mrt.c:611)
==2722== by 0x11A26C: delete_mrtentry (mrt.c:701)
==2722== by 0x127184: age_routes (timer.c:1215)
==2722== by 0x11492D: timer (main.c:577)
==2722== by 0x10AF09: age_callout_queue (callout.c:130)
==2722== by 0x10AA55: main (main.c:523)
==2722== Block was alloc'd at
==2722== at 0x483577F: malloc (vg_replace_malloc.c:299)
==2722== by 0x12649A: add_rp_grp_entry (rp.c:658)
==2722== by 0x1258A5: rp_grp_match (rp.c:1274)
==2722== by 0x11AE27: find_route (mrt.c:294)
==2722== by 0x124981: process_cache_miss (route.c:1007)
==2722== by 0x124981: process_kernel_call (route.c:924)
==2722== by 0x10AB0F: main (main.c:535)
==2722==
==2722== Invalid read of size 8
==2722== at 0x1271BF: age_routes (timer.c:424)
==2722== by 0x11492D: timer (main.c:577)
==2722== by 0x10AF09: age_callout_queue (callout.c:130)
==2722== by 0x10AA55: main (main.c:523)
==2722== Address 0x4a95140 is 0 bytes inside a block of size 32 free'd
==2722== at 0x48369AB: free (vg_replace_malloc.c:530)
==2722== by 0x125F6A: delete_rp_grp_entry (rp.c:756)
==2722== by 0x119F9B: delete_grpentry (mrt.c:611)
==2722== by 0x11A26C: delete_mrtentry (mrt.c:701)
==2722== by 0x127184: age_routes (timer.c:1215)
==2722== by 0x11492D: timer (main.c:577)
==2722== by 0x10AF09: age_callout_queue (callout.c:130)
==2722== by 0x10AA55: main (main.c:523)
==2722== Block was alloc'd at
==2722== at 0x483577F: malloc (vg_replace_malloc.c:299)
==2722== by 0x12645A: add_cand_rp (rp.c:409)
==2722== by 0x12645A: add_rp_grp_entry (rp.c:586)
==2722== by 0x1258A5: rp_grp_match (rp.c:1274)
==2722== by 0x11AE27: find_route (mrt.c:294)
==2722== by 0x124981: process_cache_miss (route.c:1007)
==2722== by 0x124981: process_kernel_call (route.c:924)
==2722== by 0x10AB0F: main (main.c:535)
[...]
It also has nothing to do with PIM Join/Prune. I get the same with no multicast listener for this group. However it's the multicast sender side triggering it. As long as I start no ping6 -i 0.2 -t 16 -q ff7e:0240:fd5c:725:2841:4203::123
everything is fine. Also if I start ping6
later, nothing happens. Only if I start ping6
to the embedded-RP address at an early point only then valgrind reports an issue for this.
If I set the group_prefix to ff3e:... (so no embedded-RP address) then valgrind reports no issue for this either. Conceptually I do not quite understand yet how this would make a difference on the RP itself. Why would the RP itself need to care if it is an embedded-RP address or not?
Shouldn't it only make a difference for either a multicast router receiving an according MLD report on its interface or a multicast router receiving a PIM Join/Prune message?
(Hm, and yes, saw the comment in main.c, that age_routes() is supposed to clean the mrtentry objects and age_misc() is supposed to clean cand-RP list and other things. But I'm wondering whether something shouldn't be added or was added wrongly in the first place)
from pim6sd.
Hm, if I just delete this section in delete_grpentry()
:
Lines 607 to 613 in 26c54d4
Then I have an issue of an RP-Set entry which was added on an intemediate node via a PIM Join/Prune never timing out.
On such an intermediate node between the listener and RP, the entry is always shown with a "Hold" and "Age" of 65535:
---------------------------RP-Set----------------------------
Current BSR address: :: Prio: 0 Timeout: 160
RP-address(Upstream)/Group prefix Prio Hold Age
fd5c:725:2841:4203::2(myself)
ff7e:240:fd5c:725:2841:4203::/96 1 65535 65535
So I guess the IF_TIMEOUT(rp_grp_entry_ptr->holdtime)
in age_misc()
therefore never applies.
I tried the easy approach of just storing the next pointer at the start of the two for loops. And both valgrind seems happy with that and entries are still deleted fine on intermediate nodes.
Going to make a PR in a second.
from pim6sd.
Btw., there were also a few more reports by valgrind with a Syscall param [...] points to uninitialised byte(s)
and on exit it reported 34 missing calls to free().
I love valgrind :-).
I guess it would make sense to try to fix these first, before any refactoring? With a clean valgrind report it'd be easier to spot and bisect memory related regressions introduced by any larger changes in the future.
from pim6sd.
Well done! Valgrind is one of the best gifts to humanity and engineers :-)
from pim6sd.
Related Issues (20)
- Make ; at end of line in .conf file optional
- Convert configuration directives from underscore to dashes
- Missing pim-join-prune in 3 router setup HOT 5
- Not forwarding multicast (Linux kernel (config) issue?) HOT 3
- Timer accuracy is way off HOT 3
- PIM Decapsulation HOT 1
- undefined reference to `yywrap' HOT 6
- Please Tag a Release HOT 2
- Code cleanup, test on musl libc using Alpine or Void Linux HOT 1
- Protocol not available HOT 4
- crash in make_mld6v2_msg with mld6v2 HOT 6
- Cannot run at the same time as pimd HOT 6
- Seg fault when interface is missing link-local address HOT 2
- Should we default to MLDv2 instead of MLDv1?
- ssm.conf.sample syntax error
- Exits after returned mld_type == 0, triggered by received UDP multicast packets
- segfault after ~5 seconds if an interface has no carrier HOT 2
- Potentially broken PIM checksum HOT 3
- RP-Set not refreshing / vanishing PIM bootstrap HOT 11
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pim6sd.