| From foo@baz Sat Apr 16 10:02:53 PDT 2016 |
| From: Roopa Prabhu <roopa@cumulusnetworks.com> |
| Date: Thu, 7 Apr 2016 21:28:38 -0700 |
| Subject: mpls: find_outdev: check for err ptr in addition to NULL check |
| |
| From: Roopa Prabhu <roopa@cumulusnetworks.com> |
| |
| [ Upstream commit 94a57f1f8a9de90ab4b0f8748361ff8be706c80c ] |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/mpls/af_mpls.c | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/net/mpls/af_mpls.c |
| +++ b/net/mpls/af_mpls.c |
| @@ -518,6 +518,9 @@ static struct net_device *find_outdev(st |
| if (!dev) |
| return ERR_PTR(-ENODEV); |
| |
| + if (IS_ERR(dev)) |
| + return dev; |
| + |
| /* The caller is holding rtnl anyways, so release the dev reference */ |
| dev_put(dev); |
| |