| From bippy-5f407fcff5a0 Mon Sep 17 00:00:00 2001 |
| From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| To: <linux-cve-announce@vger.kernel.org> |
| Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org> |
| Subject: CVE-2021-47371: nexthop: Fix memory leaks in nexthop notification chain listeners |
| |
| Description |
| =========== |
| |
| In the Linux kernel, the following vulnerability has been resolved: |
| |
| nexthop: Fix memory leaks in nexthop notification chain listeners |
| |
| syzkaller discovered memory leaks [1] that can be reduced to the |
| following commands: |
| |
| # ip nexthop add id 1 blackhole |
| # devlink dev reload pci/0000:06:00.0 |
| |
| As part of the reload flow, mlxsw will unregister its netdevs and then |
| unregister from the nexthop notification chain. Before unregistering |
| from the notification chain, mlxsw will receive delete notifications for |
| nexthop objects using netdevs registered by mlxsw or their uppers. mlxsw |
| will not receive notifications for nexthops using netdevs that are not |
| dismantled as part of the reload flow. For example, the blackhole |
| nexthop above that internally uses the loopback netdev as its nexthop |
| device. |
| |
| One way to fix this problem is to have listeners flush their nexthop |
| tables after unregistering from the notification chain. This is |
| error-prone as evident by this patch and also not symmetric with the |
| registration path where a listener receives a dump of all the existing |
| nexthops. |
| |
| Therefore, fix this problem by replaying delete notifications for the |
| listener being unregistered. This is symmetric to the registration path |
| and also consistent with the netdev notification chain. |
| |
| The above means that unregister_nexthop_notifier(), like |
| register_nexthop_notifier(), will have to take RTNL in order to iterate |
| over the existing nexthops and that any callers of the function cannot |
| hold RTNL. This is true for mlxsw and netdevsim, but not for the VXLAN |
| driver. To avoid a deadlock, change the latter to unregister its nexthop |
| listener without holding RTNL, making it symmetric to the registration |
| path. |
| |
| [1] |
| unreferenced object 0xffff88806173d600 (size 512): |
| comm "syz-executor.0", pid 1290, jiffies 4295583142 (age 143.507s) |
| hex dump (first 32 bytes): |
| 41 9d 1e 60 80 88 ff ff 08 d6 73 61 80 88 ff ff A..`......sa.... |
| 08 d6 73 61 80 88 ff ff 01 00 00 00 00 00 00 00 ..sa............ |
| backtrace: |
| [<ffffffff81a6b576>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] |
| [<ffffffff81a6b576>] slab_post_alloc_hook+0x96/0x490 mm/slab.h:522 |
| [<ffffffff81a716d3>] slab_alloc_node mm/slub.c:3206 [inline] |
| [<ffffffff81a716d3>] slab_alloc mm/slub.c:3214 [inline] |
| [<ffffffff81a716d3>] kmem_cache_alloc_trace+0x163/0x370 mm/slub.c:3231 |
| [<ffffffff82e8681a>] kmalloc include/linux/slab.h:591 [inline] |
| [<ffffffff82e8681a>] kzalloc include/linux/slab.h:721 [inline] |
| [<ffffffff82e8681a>] mlxsw_sp_nexthop_obj_group_create drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:4918 [inline] |
| [<ffffffff82e8681a>] mlxsw_sp_nexthop_obj_new drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:5054 [inline] |
| [<ffffffff82e8681a>] mlxsw_sp_nexthop_obj_event+0x59a/0x2910 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:5239 |
| [<ffffffff813ef67d>] notifier_call_chain+0xbd/0x210 kernel/notifier.c:83 |
| [<ffffffff813f0662>] blocking_notifier_call_chain kernel/notifier.c:318 [inline] |
| [<ffffffff813f0662>] blocking_notifier_call_chain+0x72/0xa0 kernel/notifier.c:306 |
| [<ffffffff8384b9c6>] call_nexthop_notifiers+0x156/0x310 net/ipv4/nexthop.c:244 |
| [<ffffffff83852bd8>] insert_nexthop net/ipv4/nexthop.c:2336 [inline] |
| [<ffffffff83852bd8>] nexthop_add net/ipv4/nexthop.c:2644 [inline] |
| [<ffffffff83852bd8>] rtm_new_nexthop+0x14e8/0x4d10 net/ipv4/nexthop.c:2913 |
| [<ffffffff833e9a78>] rtnetlink_rcv_msg+0x448/0xbf0 net/core/rtnetlink.c:5572 |
| [<ffffffff83608703>] netlink_rcv_skb+0x173/0x480 net/netlink/af_netlink.c:2504 |
| [<ffffffff833de032>] rtnetlink_rcv+0x22/0x30 net/core/rtnetlink.c:5590 |
| [<ffffffff836069de>] netlink_unicast_kernel net/netlink/af_netlink.c:1314 [inline] |
| [<ffffffff836069de>] netlink_unicast+0x5ae/0x7f0 net/netlink/af_netlink.c:1340 |
| [<ffffffff83607501>] netlink_sendmsg+0x8e1/0xe30 net/netlink/af_netlink.c:1929 |
| [<ffffffff832fde84>] sock_sendmsg_nosec net/socket.c:704 [inline] |
| [<ffffffff832fde84>] sock_sendmsg net/socket.c:724 [inline] |
| [<ffffffff832fde84>] ____sys_sendmsg+0x874/0x9f0 net/socket.c:2409 |
| [<ffffffff83304a44>] ___sys_sendmsg+0x104/0x170 net/socket.c:2463 |
| [<ffffffff83304c01>] __sys_sendmsg+0x111/0x1f0 net/socket.c:2492 |
| [<ffffffff83304d5d>] __do_sys_sendmsg net/socket.c:2501 [inline] |
| [<ffffffff83304d5d>] __se_sys_sendmsg net/socket.c:2499 [inline] |
| [<ffffffff83304d5d>] __x64_sys_sendmsg+0x7d/0xc0 net/socket.c:2499 |
| |
| The Linux kernel CVE team has assigned CVE-2021-47371 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Issue introduced in 5.11 with commit 2a014b200bbd973cc96e082a5bc445fe20b50f32 and fixed in 5.14.9 with commit 741760fa6252628a3d3afad439b72437d4b123d9 |
| Issue introduced in 5.11 with commit 2a014b200bbd973cc96e082a5bc445fe20b50f32 and fixed in 5.15 with commit 3106a0847525befe3e22fc723909d1b21eb0d520 |
| |
| Please see https://www.kernel.org for a full list of currently supported |
| kernel versions by the kernel community. |
| |
| Unaffected versions might change over time as fixes are backported to |
| older supported kernel versions. The official CVE entry at |
| https://cve.org/CVERecord/?id=CVE-2021-47371 |
| will be updated if fixes are backported, please check that for the most |
| up to date information about this issue. |
| |
| |
| Affected files |
| ============== |
| |
| The file(s) affected by this issue are: |
| drivers/net/vxlan.c |
| net/ipv4/nexthop.c |
| |
| |
| Mitigation |
| ========== |
| |
| The Linux kernel CVE team recommends that you update to the latest |
| stable kernel version for this, and many other bugfixes. Individual |
| changes are never tested alone, but rather are part of a larger kernel |
| release. Cherry-picking individual commits is not recommended or |
| supported by the Linux kernel community at all. If however, updating to |
| the latest release is impossible, the individual changes to resolve this |
| issue can be found at these commits: |
| https://git.kernel.org/stable/c/741760fa6252628a3d3afad439b72437d4b123d9 |
| https://git.kernel.org/stable/c/3106a0847525befe3e22fc723909d1b21eb0d520 |