Skip to content

Commit

Permalink
net: mpls: fix stale pointer if allocation fails during device rename
Browse files Browse the repository at this point in the history
commit fda6c89 upstream.

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: 0fae3bf ("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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Jakub Kicinski authored and Greg Kroah-Hartman committed Feb 22, 2023
1 parent 736f8f6 commit df099e6
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions net/mpls/af_mpls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,7 @@ static int mpls_dev_sysctl_register(struct net_device *dev,
free:
kfree(table);
out:
mdev->sysctl = NULL;
return -ENOBUFS;
}

Expand All @@ -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);
Expand Down

0 comments on commit df099e6

Please sign in to comment.