[packages] olsrd: fix stack corruption in net_output()
[openwrt/svn-archive/archive.git] / net / olsrd / patches / 100-olsrd-fix-stack-corruption-in-net_output.patch
1 From f4d250ad4fad5fcfe5b5feaac3f3e121adef3fba Mon Sep 17 00:00:00 2001
2 From: Jo-Philipp Wich <jow@openwrt.org>
3 Date: Fri, 22 Jun 2012 03:17:59 +0200
4 Subject: [PATCH] olsrd: fix stack corruption in net_output()
5
6 The net_output() function indirectly uses the stack variables dst and dst6
7 outside of the scope they're declared in, this might leads to olsr_sendto()
8 being called with a corrupted destination sockaddr_in.
9
10 This failure condition can be observed in the log, olsrd will continuosly
11 print "sendto(v4): Invalid Argument" or a similar message. On ARM it has been
12 reported to result in "Unsupported Address Family".
13
14 This bug became apparant on a custon OpenWrt x86_64 uClibc target using the
15 Linaro GCC 4.7-2012.04 compiler, it has been reported for an unspecified ARM
16 target as well.
17
18 The offending code seems to be unchanged since 2008 and it does not cause
19 issues on 32bit systems and/or with older (Linaro) GCC versions, but the
20 compiler used in our tests seems to perform more aggressive optimizations
21 leading to a stack corruption.
22 ---
23 src/net_olsr.c | 4 ++--
24 1 files changed, 2 insertions(+), 2 deletions(-)
25
26 --- a/src/net_olsr.c
27 +++ b/src/net_olsr.c
28 @@ -336,6 +336,8 @@ net_output(struct interface *ifp)
29 {
30 struct sockaddr_in *sin = NULL;
31 struct sockaddr_in6 *sin6 = NULL;
32 + struct sockaddr_in dst;
33 + struct sockaddr_in6 dst6;
34 struct ptf *tmp_ptf_list;
35 union olsr_packet *outmsg;
36 int retval;
37 @@ -354,7 +356,6 @@ net_output(struct interface *ifp)
38 outmsg->v4.olsr_packlen = htons(ifp->netbuf.pending);
39
40 if (olsr_cnf->ip_version == AF_INET) {
41 - struct sockaddr_in dst;
42 /* IP version 4 */
43 sin = (struct sockaddr_in *)&ifp->int_broadaddr;
44
45 @@ -365,7 +366,6 @@ net_output(struct interface *ifp)
46 if (sin->sin_port == 0)
47 sin->sin_port = htons(olsr_cnf->olsrport);
48 } else {
49 - struct sockaddr_in6 dst6;
50 /* IP version 6 */
51 sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;
52 /* Copy sin */