1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Date: Thu, 26 Apr 2007 04:56:57 +0000 (-0700)
Subject: [PATCH] IPV6: Disallow RH0 by default.
X-Git-Tag: v2.6.20.9~1
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fstable%2Flinux-2.6.20.y.git;a=commitdiff_plain;h=010831ab8436dfd9304b203467566fb6b135c24f
[PATCH] IPV6: Disallow RH0 by default.
[IPV6]: Disallow RH0 by default.
A security issue is emerging. Disallow Routing Header Type 0 by default
as we have been doing for IPv4.
Note: We allow RH2 by default because it is harmless.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
Backported to Debian's 2.6.18 by dann frazier and Vlad Yasevich
diff -urpN linux-source-2.6.18.orig/Documentation/networking/ip-sysctl.txt linux-source-2.6.18/Documentation/networking/ip-sysctl.txt
--- linux-source-2.6.18.orig/Documentation/networking/ip-sysctl.txt 2007-05-11 15:09:21.000000000 -0600
+++ linux-source-2.6.18/Documentation/networking/ip-sysctl.txt 2007-05-11 15:10:03.000000000 -0600
@@ -775,6 +775,14 @@ accept_redirects - BOOLEAN
Functional default: enabled if local forwarding is disabled.
disabled if local forwarding is enabled.
+accept_source_route - INTEGER
+ Accept source routing (routing extension header).
+
+ > 0: Accept routing header.
+ = 0: Do not accept routing header.
+
+ Default: 0
+
autoconf - BOOLEAN
Autoconfigure addresses using Prefix Information in Router
Advertisements.
diff -urpN linux-source-2.6.18.orig/include/linux/ipv6.h linux-source-2.6.18/include/linux/ipv6.h
--- linux-source-2.6.18.orig/include/linux/ipv6.h 2007-05-11 15:09:21.000000000 -0600
+++ linux-source-2.6.18/include/linux/ipv6.h 2007-05-11 15:10:03.000000000 -0600
@@ -153,6 +153,7 @@ struct ipv6_devconf {
__s32 accept_ra_rt_info_max_plen;
#endif
#endif
+ __s32 accept_source_route;
void *sysctl;
};
@@ -180,6 +181,7 @@ enum {
DEVCONF_ACCEPT_RA_RTR_PREF,
DEVCONF_RTR_PROBE_INTERVAL,
DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
+ DEVCONF_ACCEPT_SOURCE_ROUTE,
DEVCONF_MAX
};
diff -urpN linux-source-2.6.18.orig/include/linux/sysctl.h linux-source-2.6.18/include/linux/sysctl.h
--- linux-source-2.6.18.orig/include/linux/sysctl.h 2007-05-11 15:09:21.000000000 -0600
+++ linux-source-2.6.18/include/linux/sysctl.h 2007-05-11 15:10:03.000000000 -0600
@@ -553,6 +553,7 @@ enum {
NET_IPV6_ACCEPT_RA_RTR_PREF=20,
NET_IPV6_RTR_PROBE_INTERVAL=21,
NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22,
+ NET_IPV6_ACCEPT_SOURCE_ROUTE=23,
__NET_IPV6_MAX
};
diff -urpN linux-source-2.6.18.orig/net/ipv6/addrconf.c linux-source-2.6.18/net/ipv6/addrconf.c
--- linux-source-2.6.18.orig/net/ipv6/addrconf.c 2007-05-11 15:09:21.000000000 -0600
+++ linux-source-2.6.18/net/ipv6/addrconf.c 2007-05-11 15:10:07.000000000 -0600
@@ -173,6 +173,7 @@ struct ipv6_devconf ipv6_devconf = {
.accept_ra_rt_info_max_plen = 0,
#endif
#endif
+ .accept_source_route = 0, /* we do not accept RH0 by default. */
};
static struct ipv6_devconf ipv6_devconf_dflt = {
@@ -203,6 +204,7 @@ static struct ipv6_devconf ipv6_devconf_
.accept_ra_rt_info_max_plen = 0,
#endif
#endif
+ .accept_source_route = 0, /* we do not accept RH0 by default. */
};
/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
@@ -3333,6 +3335,7 @@ static void inline ipv6_store_devconf(st
array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
#endif
#endif
+ array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
}
/* Maximum length of ifinfomsg attributes */
@@ -3847,6 +3850,14 @@ static struct addrconf_sysctl_table
#endif
#endif
{
+ .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE,
+ .procname = "accept_source_route",
+ .data = &ipv6_devconf.accept_source_route,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
.ctl_name = 0, /* sentinel */
}
},
diff -urpN linux-source-2.6.18.orig/net/ipv6/exthdrs.c linux-source-2.6.18/net/ipv6/exthdrs.c
--- linux-source-2.6.18.orig/net/ipv6/exthdrs.c 2007-05-11 15:09:21.000000000 -0600
+++ linux-source-2.6.18/net/ipv6/exthdrs.c 2007-05-11 15:10:03.000000000 -0600
@@ -221,10 +221,24 @@ static int ipv6_rthdr_rcv(struct sk_buff
struct inet6_skb_parm *opt = IP6CB(skb);
struct in6_addr *addr;
struct in6_addr daddr;
+ struct inet6_dev *idev;
int n, i;
-
struct ipv6_rt_hdr *hdr;
struct rt0_hdr *rthdr;
+ int accept_source_route = ipv6_devconf.accept_source_route;
+
+ if (accept_source_route == 0 ||
+ ((idev = in6_dev_get(skb->dev)) == NULL)) {
+ kfree_skb(skb);
+ return -1;
+ }
+ if (idev->cnf.accept_source_route == 0) {
+ in6_dev_put(idev);
+ kfree_skb(skb);
+ return -1;
+ }
+
+ in6_dev_put(idev);
if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
!pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
@@ -235,6 +249,12 @@ static int ipv6_rthdr_rcv(struct sk_buff
hdr = (struct ipv6_rt_hdr *) skb->h.raw;
+ if (hdr->type != IPV6_SRCRT_TYPE_0) {
+ IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
+ icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
+ return -1;
+ }
+
if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
skb->pkt_type != PACKET_HOST) {
IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
@@ -253,12 +273,6 @@ looped_back:
return 1;
}
- if (hdr->type != IPV6_SRCRT_TYPE_0) {
- IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
- icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
- return -1;
- }
-
if (hdr->hdrlen & 0x01) {
IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
|