NETDEV_DOWN and NETDEV_UNREGISTER flush a device's offloaded SAs with
xfrm_dev_state_flush(). It deletes each SA under x->lock and then frees
its offload binding with xfrm_dev_state_free() without that lock: the
driver frees its offload state, xso.dev is cleared and the device
reference is dropped. Netlink requests that hold only a reference to
the SA can still be using the binding after they checked xso.dev:
1/2 The offload statistics refresh in GETSA, ALLOCSPI replies and SA
notifications, and in the expiry timer, calls into the driver.
Refresh the statistics only of SAs that are not dead, under
x->lock, which orders the refresh with the teardown.
2/2 XFRM_MSG_MIGRATE_STATE reads the ifindex through xso.dev. Use the
ifindex cached at attachment, as state dumps already do.
Cen Zhang (2):
xfrm: protect offload statistics updates from device teardown
xfrm: use cached offload ifindex when migrating an SA
net/xfrm/xfrm_state.c | 4 ++--
net/xfrm/xfrm_user.c | 14 +++++++++++---
2 files changed, 13 insertions(+), 5 deletions(-)
---
Changes in v2:
- Address the incomplete RCU protection raised by Sashiko:
https://sashiko.dev/#/patchset/97864
- Patch 1: refresh the statistics under x->lock and only for SAs that are
not dead, instead of using RCU, which covered neither the driver offload
state nor the cleared xso.dev; fix the same race in the expiry timer.
- Add patch 2 for the same race in xfrm_do_migrate_state(), also raised by
Sashiko.
- Trim the crash reports.
Link to v1: https://lore.kernel.org/r/pm-xfrm-core-objects-candidate-0050-v3-dbfb7194ffb750193d02@gmail.com (local)