diff mbox series

[SRU,OEM-5.17,OEM-6.0,1/1] net: mpls: fix stale pointer if allocation fails during device rename

Message ID 20230411225512.211644-2-cengiz.can@canonical.com
State New
Headers show
Series CVE-2023-26545 | expand

Commit Message

Cengiz Can April 11, 2023, 10:55 p.m. UTC
From: Jakub Kicinski <kuba@kernel.org>

lianhui reports that when MPLS fails to register the sysctl table
under new location (during device rename) the old pointers won't
get overwritten and may be freed again (double free).

Handle this gracefully. The best option would be unregistering
the MPLS from the device completely on failure, but unfortunately
mpls_ifdown() can fail. So failing fully is also unreliable.

Another option is to register the new table first then only
remove old one if the new one succeeds. That requires more
code, changes order of notifications and two tables may be
visible at the same time.

sysctl point is not used in the rest of the code - set to NULL
on failures and skip unregister if already NULL.

Reported-by: lianhui tang <bluetlh@gmail.com>
Fixes: 0fae3bf018d9 ("mpls: handle device renames for per-device sysctls")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
CVE-2023-26545
(cherry picked from commit fda6c89fe3d9aca073495a664e1d5aea28cd4377)
Signed-off-by: Cengiz Can <cengiz.can@canonical.com>
---
 net/mpls/af_mpls.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Roxana Nicolescu April 12, 2023, 7:09 a.m. UTC | #1
On 12/04/2023 00:55, Cengiz Can wrote:
> From: Jakub Kicinski <kuba@kernel.org>
>
> lianhui reports that when MPLS fails to register the sysctl table
> under new location (during device rename) the old pointers won't
> get overwritten and may be freed again (double free).
>
> Handle this gracefully. The best option would be unregistering
> the MPLS from the device completely on failure, but unfortunately
> mpls_ifdown() can fail. So failing fully is also unreliable.
>
> Another option is to register the new table first then only
> remove old one if the new one succeeds. That requires more
> code, changes order of notifications and two tables may be
> visible at the same time.
>
> sysctl point is not used in the rest of the code - set to NULL
> on failures and skip unregister if already NULL.
>
> Reported-by: lianhui tang <bluetlh@gmail.com>
> Fixes: 0fae3bf018d9 ("mpls: handle device renames for per-device sysctls")
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> CVE-2023-26545
> (cherry picked from commit fda6c89fe3d9aca073495a664e1d5aea28cd4377)
> Signed-off-by: Cengiz Can <cengiz.can@canonical.com>
> ---
>   net/mpls/af_mpls.c | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
> index d6fdc5782d33..cfb8b3594df6 100644
> --- a/net/mpls/af_mpls.c
> +++ b/net/mpls/af_mpls.c
> @@ -1428,6 +1428,7 @@ static int mpls_dev_sysctl_register(struct net_device *dev,
>   free:
>   	kfree(table);
>   out:
> +	mdev->sysctl = NULL;
>   	return -ENOBUFS;
>   }
>   
> @@ -1437,6 +1438,9 @@ static void mpls_dev_sysctl_unregister(struct net_device *dev,
>   	struct net *net = dev_net(dev);
>   	struct ctl_table *table;
>   
> +	if (!mdev->sysctl)
> +		return;
> +
>   	table = mdev->sysctl->ctl_table_arg;
>   	unregister_net_sysctl_table(mdev->sysctl);
>   	kfree(table);
>
Acked-by: Roxana Nicolescu <roxana.nicolescu@canonical.com>
diff mbox series

Patch

diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index d6fdc5782d33..cfb8b3594df6 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1428,6 +1428,7 @@  static int mpls_dev_sysctl_register(struct net_device *dev,
 free:
 	kfree(table);
 out:
+	mdev->sysctl = NULL;
 	return -ENOBUFS;
 }
 
@@ -1437,6 +1438,9 @@  static void mpls_dev_sysctl_unregister(struct net_device *dev,
 	struct net *net = dev_net(dev);
 	struct ctl_table *table;
 
+	if (!mdev->sysctl)
+		return;
+
 	table = mdev->sysctl->ctl_table_arg;
 	unregister_net_sysctl_table(mdev->sysctl);
 	kfree(table);