Skip to content

Commit 7de8827

Browse files
committed
Merge branch 'ipv6-blackhole-route-fix'
Martin KaFai Lau says: ==================== ipv6: Initialize rt6_info properly in ip6_blackhole_route() This patchset ensures the rt6_info's fields are initialized properly in ip6_blackhole_route() where xfrm_policy is the primarily user. The first patch is a prep work. The second patch is the fix. It fixes d52d399 ("ipv6: Create percpu rt6_info"). Here is the oops reported by Phil Sutter <phil@nwl.cc>: BUG: unable to handle kernel NULL pointer dereference at 00000000000000a0 IP: [<ffffffff8171a95e>] __ip6_datagram_connect+0x71e/0xa20 PGD c2cb1067 PUD c2d7a067 PMD 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: cmac nfs lockd grace sunrpc bridge stp llc nvidia(PO) snd_usb_audio snd_usbmidi_lib iTCO_wdt CPU: 1 PID: 2964 Comm: ping6 Tainted: P O 4.2.1-aufs torvalds#10 Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./4Core1333-Viiv, BIOS P1.60 07/01/2008 task: ffff8800ca62bc00 ti: ffff880129a14000 task.ti: ffff880129a14000 RIP: 0010:[<ffffffff8171a95e>] [<ffffffff8171a95e>] __ip6_datagram_connect+0x71e/0xa20 RSP: 0018:ffff880129a17da8 EFLAGS: 00010296 RAX: 000000000000000b RBX: 0000000000000000 RCX: 0000000000000006 RDX: 0000000000000007 RSI: 0000000000000246 RDI: ffff88012fc8d5a0 RBP: ffff8800cb9a9048 R08: 756e207369207472 R09: 216c6c756e207369 R10: 0000000000000665 R11: 0000000000000006 R12: ffff8800cb9a8cf8 R13: ffff8800cb9a8cf8 R14: 0000000000000000 R15: ffff8800cb9a8cc0 FS: 00007fb76ad74700(0000) GS:ffff88012fc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000000a0 CR3: 00000000c2dba000 CR4: 00000000000406e0 Stack: ffff8800cb9a9048 ffff8800cb9a8de0 ffff8800cb9feb70 ffffffff816b2c41 00007fb70000000b ffffea0000df7200 ffff8800cb9f5cfc ffff8800cb9a8cc0 03fffffffe068a20 ffff8800cb9a8cc0 ffffffff817097c0 0000000100000000 Call Trace: [<ffffffff816b2c41>] ? udp_lib_get_port+0x1a1/0x380 [<ffffffff817097c0>] ? udpv6_rcv+0x20/0x20 [<ffffffff8171ac82>] ? ip6_datagram_connect+0x22/0x40 [<ffffffff8163ae9b>] ? SyS_connect+0x6b/0xb0 [<ffffffff810767ac>] ? __do_page_fault+0x15c/0x380 [<ffffffff8163a8d3>] ? SyS_socket+0x63/0xa0 [<ffffffff81741957>] ? entry_SYSCALL_64_fastpath+0x12/0x6a Code: ba ae 00 00 00 48 c7 c6 7b 71 94 81 48 c7 c7 63 71 94 81 e8 6c 0f 02 00 48 85 db 75 0e 48 c7 c7 9f 71 94 81 31 c0 e8 59 0f 02 00 <48> 83 bb a0 00 00 00 00 75 0e 48 c7 c7 ae 71 94 81 31 c0 e8 41 RIP [<ffffffff8171a95e>] __ip6_datagram_connect+0x71e/0xa20 RSP <ffff880129a17da8> CR2: 00000000000000a0 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 53ca376 + 0a1f596 commit 7de8827

File tree

1 file changed

+16
-21
lines changed

1 file changed

+16
-21
lines changed

net/ipv6/route.c

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,6 @@ static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
248248
{
249249
}
250250

251-
static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst,
252-
unsigned long old)
253-
{
254-
return NULL;
255-
}
256-
257251
static struct dst_ops ip6_dst_blackhole_ops = {
258252
.family = AF_INET6,
259253
.destroy = ip6_dst_destroy,
@@ -262,7 +256,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
262256
.default_advmss = ip6_default_advmss,
263257
.update_pmtu = ip6_rt_blackhole_update_pmtu,
264258
.redirect = ip6_rt_blackhole_redirect,
265-
.cow_metrics = ip6_rt_blackhole_cow_metrics,
259+
.cow_metrics = dst_cow_metrics_generic,
266260
.neigh_lookup = ip6_neigh_lookup,
267261
};
268262

@@ -319,6 +313,15 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
319313

320314
#endif
321315

316+
static void rt6_info_init(struct rt6_info *rt)
317+
{
318+
struct dst_entry *dst = &rt->dst;
319+
320+
memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
321+
INIT_LIST_HEAD(&rt->rt6i_siblings);
322+
INIT_LIST_HEAD(&rt->rt6i_uncached);
323+
}
324+
322325
/* allocate dst with ip6_dst_ops */
323326
static struct rt6_info *__ip6_dst_alloc(struct net *net,
324327
struct net_device *dev,
@@ -327,13 +330,9 @@ static struct rt6_info *__ip6_dst_alloc(struct net *net,
327330
struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
328331
0, DST_OBSOLETE_FORCE_CHK, flags);
329332

330-
if (rt) {
331-
struct dst_entry *dst = &rt->dst;
333+
if (rt)
334+
rt6_info_init(rt);
332335

333-
memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
334-
INIT_LIST_HEAD(&rt->rt6i_siblings);
335-
INIT_LIST_HEAD(&rt->rt6i_uncached);
336-
}
337336
return rt;
338337
}
339338

@@ -1214,24 +1213,20 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
12141213

12151214
rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, DST_OBSOLETE_NONE, 0);
12161215
if (rt) {
1217-
new = &rt->dst;
1218-
1219-
memset(new + 1, 0, sizeof(*rt) - sizeof(*new));
1216+
rt6_info_init(rt);
12201217

1218+
new = &rt->dst;
12211219
new->__use = 1;
12221220
new->input = dst_discard;
12231221
new->output = dst_discard_sk;
12241222

1225-
if (dst_metrics_read_only(&ort->dst))
1226-
new->_metrics = ort->dst._metrics;
1227-
else
1228-
dst_copy_metrics(new, &ort->dst);
1223+
dst_copy_metrics(new, &ort->dst);
12291224
rt->rt6i_idev = ort->rt6i_idev;
12301225
if (rt->rt6i_idev)
12311226
in6_dev_hold(rt->rt6i_idev);
12321227

12331228
rt->rt6i_gateway = ort->rt6i_gateway;
1234-
rt->rt6i_flags = ort->rt6i_flags;
1229+
rt->rt6i_flags = ort->rt6i_flags & ~RTF_PCPU;
12351230
rt->rt6i_metric = 0;
12361231

12371232
memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));

0 commit comments

Comments
 (0)