Skip to content

Commit f895f0c

Browse files
committed
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Conflicts: net/ipv4/ip_vti.c Steffen Klassert says: ==================== pull request (net): ipsec 2014-05-15 This pull request has a merge conflict in net/ipv4/ip_vti.c between commit 8d89dcd ("vti: don't allow to add the same tunnel twice") and commit a324523 ("vti4:Don't count header length twice"). It can be solved like it is done in linux-next. 1) Fix a ipv6 xfrm output crash when a packet is rerouted by netfilter to not use IPsec. 2) vti4 counts some header lengths twice leading to an incorrect device mtu. Fix this by counting these headers only once. 3) We don't catch the case if an unsupported protocol is submitted to the xfrm protocol handlers, this can lead to NULL pointer dereferences. Fix this by adding the appropriate checks. 4) vti6 may unregister pernet ops twice on init errors. Fix this by removing one of the calls to do it only once. From Mathias Krause. 5) Set the vti tunnel mark before doing a lookup in the error handlers. Otherwise we don't find the correct xfrm state. ==================== The conflict in ip_vti.c was simple, 'net' had a commit removing a line from vti_tunnel_init() and this tree being merged had a commit adding a line to the same location. Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents b394745 + 6d004d6 commit f895f0c

File tree

6 files changed

+66
-31
lines changed

6 files changed

+66
-31
lines changed

net/ipv4/ip_vti.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
239239
static int vti4_err(struct sk_buff *skb, u32 info)
240240
{
241241
__be32 spi;
242+
__u32 mark;
242243
struct xfrm_state *x;
243244
struct ip_tunnel *tunnel;
244245
struct ip_esp_hdr *esph;
@@ -254,6 +255,8 @@ static int vti4_err(struct sk_buff *skb, u32 info)
254255
if (!tunnel)
255256
return -1;
256257

258+
mark = be32_to_cpu(tunnel->parms.o_key);
259+
257260
switch (protocol) {
258261
case IPPROTO_ESP:
259262
esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2));
@@ -281,7 +284,7 @@ static int vti4_err(struct sk_buff *skb, u32 info)
281284
return 0;
282285
}
283286

284-
x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
287+
x = xfrm_state_lookup(net, mark, (const xfrm_address_t *)&iph->daddr,
285288
spi, protocol, AF_INET);
286289
if (!x)
287290
return 0;

net/ipv4/xfrm4_output.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,38 +62,42 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
6262
if (err)
6363
return err;
6464

65-
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
66-
IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED;
67-
68-
skb->protocol = htons(ETH_P_IP);
65+
IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
6966

7067
return x->outer_mode->output2(x, skb);
7168
}
7269
EXPORT_SYMBOL(xfrm4_prepare_output);
7370

7471
int xfrm4_output_finish(struct sk_buff *skb)
7572
{
73+
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
74+
skb->protocol = htons(ETH_P_IP);
75+
76+
#ifdef CONFIG_NETFILTER
77+
IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
78+
#endif
79+
80+
return xfrm_output(skb);
81+
}
82+
83+
static int __xfrm4_output(struct sk_buff *skb)
84+
{
85+
struct xfrm_state *x = skb_dst(skb)->xfrm;
86+
7687
#ifdef CONFIG_NETFILTER
77-
if (!skb_dst(skb)->xfrm) {
88+
if (!x) {
7889
IPCB(skb)->flags |= IPSKB_REROUTED;
7990
return dst_output(skb);
8091
}
81-
82-
IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
8392
#endif
8493

85-
skb->protocol = htons(ETH_P_IP);
86-
return xfrm_output(skb);
94+
return x->outer_mode->afinfo->output_finish(skb);
8795
}
8896

8997
int xfrm4_output(struct sock *sk, struct sk_buff *skb)
9098
{
91-
struct dst_entry *dst = skb_dst(skb);
92-
struct xfrm_state *x = dst->xfrm;
93-
9499
return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb,
95-
NULL, dst->dev,
96-
x->outer_mode->afinfo->output_finish,
100+
NULL, skb_dst(skb)->dev, __xfrm4_output,
97101
!(IPCB(skb)->flags & IPSKB_REROUTED));
98102
}
99103

net/ipv4/xfrm4_protocol.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err)
5050
{
5151
int ret;
5252
struct xfrm4_protocol *handler;
53+
struct xfrm4_protocol __rcu **head = proto_handlers(protocol);
5354

54-
for_each_protocol_rcu(*proto_handlers(protocol), handler)
55+
if (!head)
56+
return 0;
57+
58+
for_each_protocol_rcu(*head, handler)
5559
if ((ret = handler->cb_handler(skb, err)) <= 0)
5660
return ret;
5761

@@ -64,15 +68,20 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
6468
{
6569
int ret;
6670
struct xfrm4_protocol *handler;
71+
struct xfrm4_protocol __rcu **head = proto_handlers(nexthdr);
6772

6873
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
6974
XFRM_SPI_SKB_CB(skb)->family = AF_INET;
7075
XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
7176

72-
for_each_protocol_rcu(*proto_handlers(nexthdr), handler)
77+
if (!head)
78+
goto out;
79+
80+
for_each_protocol_rcu(*head, handler)
7381
if ((ret = handler->input_handler(skb, nexthdr, spi, encap_type)) != -EINVAL)
7482
return ret;
7583

84+
out:
7685
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
7786

7887
kfree_skb(skb);
@@ -208,6 +217,9 @@ int xfrm4_protocol_register(struct xfrm4_protocol *handler,
208217
int ret = -EEXIST;
209218
int priority = handler->priority;
210219

220+
if (!proto_handlers(protocol) || !netproto(protocol))
221+
return -EINVAL;
222+
211223
mutex_lock(&xfrm4_protocol_mutex);
212224

213225
if (!rcu_dereference_protected(*proto_handlers(protocol),
@@ -250,6 +262,9 @@ int xfrm4_protocol_deregister(struct xfrm4_protocol *handler,
250262
struct xfrm4_protocol *t;
251263
int ret = -ENOENT;
252264

265+
if (!proto_handlers(protocol) || !netproto(protocol))
266+
return -EINVAL;
267+
253268
mutex_lock(&xfrm4_protocol_mutex);
254269

255270
for (pprev = proto_handlers(protocol);

net/ipv6/ip6_vti.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
511511
u8 type, u8 code, int offset, __be32 info)
512512
{
513513
__be32 spi;
514+
__u32 mark;
514515
struct xfrm_state *x;
515516
struct ip6_tnl *t;
516517
struct ip_esp_hdr *esph;
@@ -524,6 +525,8 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
524525
if (!t)
525526
return -1;
526527

528+
mark = be32_to_cpu(t->parms.o_key);
529+
527530
switch (protocol) {
528531
case IPPROTO_ESP:
529532
esph = (struct ip_esp_hdr *)(skb->data + offset);
@@ -545,7 +548,7 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
545548
type != NDISC_REDIRECT)
546549
return 0;
547550

548-
x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
551+
x = xfrm_state_lookup(net, mark, (const xfrm_address_t *)&iph->daddr,
549552
spi, protocol, AF_INET6);
550553
if (!x)
551554
return 0;
@@ -1097,7 +1100,6 @@ static int __init vti6_tunnel_init(void)
10971100

10981101
err = xfrm6_protocol_register(&vti_esp6_protocol, IPPROTO_ESP);
10991102
if (err < 0) {
1100-
unregister_pernet_device(&vti6_net_ops);
11011103
pr_err("%s: can't register vti6 protocol\n", __func__);
11021104

11031105
goto out;
@@ -1106,7 +1108,6 @@ static int __init vti6_tunnel_init(void)
11061108
err = xfrm6_protocol_register(&vti_ah6_protocol, IPPROTO_AH);
11071109
if (err < 0) {
11081110
xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP);
1109-
unregister_pernet_device(&vti6_net_ops);
11101111
pr_err("%s: can't register vti6 protocol\n", __func__);
11111112

11121113
goto out;
@@ -1116,7 +1117,6 @@ static int __init vti6_tunnel_init(void)
11161117
if (err < 0) {
11171118
xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH);
11181119
xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP);
1119-
unregister_pernet_device(&vti6_net_ops);
11201120
pr_err("%s: can't register vti6 protocol\n", __func__);
11211121

11221122
goto out;

net/ipv6/xfrm6_output.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,6 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
114114
if (err)
115115
return err;
116116

117-
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
118-
#ifdef CONFIG_NETFILTER
119-
IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
120-
#endif
121-
122-
skb->protocol = htons(ETH_P_IPV6);
123117
skb->local_df = 1;
124118

125119
return x->outer_mode->output2(x, skb);
@@ -128,11 +122,13 @@ EXPORT_SYMBOL(xfrm6_prepare_output);
128122

129123
int xfrm6_output_finish(struct sk_buff *skb)
130124
{
125+
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
126+
skb->protocol = htons(ETH_P_IPV6);
127+
131128
#ifdef CONFIG_NETFILTER
132129
IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
133130
#endif
134131

135-
skb->protocol = htons(ETH_P_IPV6);
136132
return xfrm_output(skb);
137133
}
138134

@@ -142,6 +138,13 @@ static int __xfrm6_output(struct sk_buff *skb)
142138
struct xfrm_state *x = dst->xfrm;
143139
int mtu;
144140

141+
#ifdef CONFIG_NETFILTER
142+
if (!x) {
143+
IP6CB(skb)->flags |= IP6SKB_REROUTED;
144+
return dst_output(skb);
145+
}
146+
#endif
147+
145148
if (skb->protocol == htons(ETH_P_IPV6))
146149
mtu = ip6_skb_dst_mtu(skb);
147150
else
@@ -165,6 +168,7 @@ static int __xfrm6_output(struct sk_buff *skb)
165168

166169
int xfrm6_output(struct sock *sk, struct sk_buff *skb)
167170
{
168-
return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
169-
skb_dst(skb)->dev, __xfrm6_output);
171+
return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb,
172+
NULL, skb_dst(skb)->dev, __xfrm6_output,
173+
!(IP6CB(skb)->flags & IP6SKB_REROUTED));
170174
}

net/ipv6/xfrm6_protocol.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ int xfrm6_rcv_cb(struct sk_buff *skb, u8 protocol, int err)
5050
{
5151
int ret;
5252
struct xfrm6_protocol *handler;
53+
struct xfrm6_protocol __rcu **head = proto_handlers(protocol);
54+
55+
if (!head)
56+
return 0;
5357

5458
for_each_protocol_rcu(*proto_handlers(protocol), handler)
5559
if ((ret = handler->cb_handler(skb, err)) <= 0)
@@ -184,10 +188,12 @@ int xfrm6_protocol_register(struct xfrm6_protocol *handler,
184188
struct xfrm6_protocol __rcu **pprev;
185189
struct xfrm6_protocol *t;
186190
bool add_netproto = false;
187-
188191
int ret = -EEXIST;
189192
int priority = handler->priority;
190193

194+
if (!proto_handlers(protocol) || !netproto(protocol))
195+
return -EINVAL;
196+
191197
mutex_lock(&xfrm6_protocol_mutex);
192198

193199
if (!rcu_dereference_protected(*proto_handlers(protocol),
@@ -230,6 +236,9 @@ int xfrm6_protocol_deregister(struct xfrm6_protocol *handler,
230236
struct xfrm6_protocol *t;
231237
int ret = -ENOENT;
232238

239+
if (!proto_handlers(protocol) || !netproto(protocol))
240+
return -EINVAL;
241+
233242
mutex_lock(&xfrm6_protocol_mutex);
234243

235244
for (pprev = proto_handlers(protocol);

0 commit comments

Comments
 (0)