On 9/30/25 03:51, Haotian Zhang wrote:
When ice_adapter_new() fails, the reserved XArray entry created by xa_insert() is not released. This causes subsequent insertions at the same index to return -EBUSY, potentially leading to NULL pointer dereferences.Release the reserved entry with xa_release() when adapter allocation fails to prevent this issue. Fixes: 0f0023c649c7 ("ice: do not init struct ice_adapter more times than needed") Suggested-by: Jacob Keller <[email protected]> Signed-off-by: Haotian Zhang <[email protected]> --- Changes in v2: - Instead of checking the return value of xa_store(), fix the real bug where a failed ice_adapter_new() would leave a stale entry in the XArray. - Use xa_release() to clean up the reserved entry, as suggested by Jacob Keller.
this is a correct improvement, but please let me propose other options, with 2. being my favorite: 1. (just ice changes) change the call order to be: (note that it is under a mutex) xa_load() // return early if another adapter exists xa_reserve() // return early if no mem ice_adapter_new() // return early if err xa_store() 2. (xarray changes) (perhaps I'm biased as the one introducing the error on error path): change xa_insert() to return 0 or -EEXIST when used as a reserving call (IOW: caller wanted to reserve, entry is reserved, so return should be 0 (or -EEXIST if we really want to differentiate in the callers)).
--- drivers/net/ethernet/intel/ice/ice_adapter.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.c b/drivers/net/ethernet/intel/ice/ice_adapter.c index b53561c34708..9eb100b11439 100644 --- a/drivers/net/ethernet/intel/ice/ice_adapter.c +++ b/drivers/net/ethernet/intel/ice/ice_adapter.c @@ -110,8 +110,10 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev) return ERR_PTR(err);adapter = ice_adapter_new(pdev);- if (!adapter) + if (!adapter) { + xa_release(&ice_adapters, index); return ERR_PTR(-ENOMEM); + } xa_store(&ice_adapters, index, adapter, GFP_KERNEL); } return adapter;
