mpls: find_outdev: check for err ptr in addition to NULL check
find_outdev calls inet{,6}_fib_lookup_dev() or dev_get_by_index() to
find the output device. In case of an error, inet{,6}_fib_lookup_dev()
returns error pointer and dev_get_by_index() returns NULL. But the function
only checks for NULL and thus can end up calling dev_put on an ERR_PTR.
This patch adds an additional check for err ptr after the NULL check.
Before: Trying to add an mpls route with no oif from user, no available
path to 10.1.1.8 and no default route:
$ip -f mpls route add 100 as 200 via inet 10.1.1.8
[ 822.337195] BUG: unable to handle kernel NULL pointer dereference at
00000000000003a3
[ 822.340033] IP: [<
ffffffff8148781e>] mpls_nh_assign_dev+0x10b/0x182
[ 822.340033] PGD
1db38067 PUD
1de9e067 PMD 0
[ 822.340033] Oops: 0000 [#1] SMP
[ 822.340033] Modules linked in:
[ 822.340033] CPU: 0 PID: 11148 Comm: ip Not tainted 4.5.0-rc7+ #54
[ 822.340033] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS
rel-1.7.5.1-0-g8936dbb-20141113_115728-nilsson.home.kraxel.org
04/01/2014
[ 822.340033] task:
ffff88001db82580 ti:
ffff88001dad4000 task.ti:
ffff88001dad4000
[ 822.340033] RIP: 0010:[<
ffffffff8148781e>] [<
ffffffff8148781e>]
mpls_nh_assign_dev+0x10b/0x182
[ 822.340033] RSP: 0018:
ffff88001dad7a88 EFLAGS:
00010282
[ 822.340033] RAX:
ffffffffffffff9b RBX:
ffffffffffffff9b RCX:
0000000000000002
[ 822.340033] RDX:
00000000ffffff9b RSI:
0000000000000008 RDI:
0000000000000000
[ 822.340033] RBP:
ffff88001ddc9ea0 R08:
ffff88001e9f1768 R09:
0000000000000000
[ 822.340033] R10:
ffff88001d9c1100 R11:
ffff88001e3c89f0 R12:
ffffffff8187e0c0
[ 822.340033] R13:
ffffffff8187e0c0 R14:
ffff88001ddc9e80 R15:
0000000000000004
[ 822.340033] FS:
00007ff9ed798700(0000) GS:
ffff88001fc00000(0000)
knlGS:
0000000000000000
[ 822.340033] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[ 822.340033] CR2:
00000000000003a3 CR3:
000000001de89000 CR4:
00000000000006f0
[ 822.340033] Stack:
[ 822.340033]
0000000000000000 0000000100000000 0000000000000000
0000000000000000
[ 822.340033]
0000000000000000 0801010a00000000 0000000000000000
0000000000000000
[ 822.340033]
0000000000000004 ffffffff8148749b ffffffff8187e0c0
000000000000001c
[ 822.340033] Call Trace:
[ 822.340033] [<
ffffffff8148749b>] ? mpls_rt_alloc+0x2b/0x3e
[ 822.340033] [<
ffffffff81488e66>] ? mpls_rtm_newroute+0x358/0x3e2
[ 822.340033] [<
ffffffff810e7bbc>] ? get_page+0x5/0xa
[ 822.340033] [<
ffffffff813b7d94>] ? rtnetlink_rcv_msg+0x17e/0x191
[ 822.340033] [<
ffffffff8111794e>] ? __kmalloc_track_caller+0x8c/0x9e
[ 822.340033] [<
ffffffff813c9393>] ?
rht_key_hashfn.isra.20.constprop.57+0x14/0x1f
[ 822.340033] [<
ffffffff813b7c16>] ? __rtnl_unlock+0xc/0xc
[ 822.340033] [<
ffffffff813cb794>] ? netlink_rcv_skb+0x36/0x82
[ 822.340033] [<
ffffffff813b4507>] ? rtnetlink_rcv+0x1f/0x28
[ 822.340033] [<
ffffffff813cb2b1>] ? netlink_unicast+0x106/0x189
[ 822.340033] [<
ffffffff813cb5b3>] ? netlink_sendmsg+0x27f/0x2c8
[ 822.340033] [<
ffffffff81392ede>] ? sock_sendmsg_nosec+0x10/0x1b
[ 822.340033] [<
ffffffff81393df1>] ? ___sys_sendmsg+0x182/0x1e3
[ 822.340033] [<
ffffffff810e4f35>] ?
__alloc_pages_nodemask+0x11c/0x1e4
[ 822.340033] [<
ffffffff8110619c>] ? PageAnon+0x5/0xd
[ 822.340033] [<
ffffffff811062fe>] ? __page_set_anon_rmap+0x45/0x52
[ 822.340033] [<
ffffffff810e7bbc>] ? get_page+0x5/0xa
[ 822.340033] [<
ffffffff810e85ab>] ? __lru_cache_add+0x1a/0x3a
[ 822.340033] [<
ffffffff81087ea9>] ? current_kernel_time64+0x9/0x30
[ 822.340033] [<
ffffffff813940c4>] ? __sys_sendmsg+0x3c/0x5a
[ 822.340033] [<
ffffffff8148f597>] ?
entry_SYSCALL_64_fastpath+0x12/0x6a
[ 822.340033] Code: 83 08 04 00 00 65 ff 00 48 8b 3c 24 e8 40 7c f2 ff
eb 13 48 c7 c3 9f ff ff ff eb 0f 89 ce e8 f1 ae f1 ff 48 89 c3 48 85 db
74 15 <48> 8b 83 08 04 00 00 65 ff 08 48 81 fb 00 f0 ff ff 76 0d eb 07
[ 822.340033] RIP [<
ffffffff8148781e>] mpls_nh_assign_dev+0x10b/0x182
[ 822.340033] RSP <
ffff88001dad7a88>
[ 822.340033] CR2:
00000000000003a3
[ 822.435363] ---[ end trace
98cc65e6f6b8bf11 ]---
After patch:
$ip -f mpls route add 100 as 200 via inet 10.1.1.8
RTNETLINK answers: Network is unreachable
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Reported-by: David Miller <davem@davemloft.net>
Signed-off-by: David S. Miller <davem@davemloft.net>