Message ID | 20230411225512.211644-2-cengiz.can@canonical.com |
---|---|
State | New |
Headers | show |
Series | CVE-2023-26545 | expand |
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 --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);