Commit d49a07a
ice: fix double-call to ice_deinit_hw() during probe failure
The following (and similar) KFENCE bugs have recently been found occurring
during certain error flows of the ice_probe() function:
kernel: ==================================================================
kernel: BUG: KFENCE: use-after-free read in ice_cleanup_fltr_mgmt_struct+0x1d
kernel: Use-after-free read at 0x00000000e72fe5ed (in kfence-torvalds#223):
kernel: ice_cleanup_fltr_mgmt_struct+0x1d/0x200 [ice]
kernel: ice_deinit_hw+0x1e/0x60 [ice]
kernel: ice_probe+0x245/0x2e0 [ice]
kernel:
kernel: kfence-torvalds#223: <..snip..>
kernel: allocated by task 7553 on cpu 0 at 2243.527621s (198.108303s ago):
kernel: devm_kmalloc+0x57/0x120
kernel: ice_init_hw+0x491/0x8e0 [ice]
kernel: ice_probe+0x203/0x2e0 [ice]
kernel:
kernel: freed by task 7553 on cpu 0 at 2441.509158s (0.175707s ago):
kernel: ice_deinit_hw+0x1e/0x60 [ice]
kernel: ice_init+0x1ad/0x570 [ice]
kernel: ice_probe+0x22b/0x2e0 [ice]
kernel:
kernel: ==================================================================
These occur as the result of a double-call to ice_deinit_hw(). This double
call happens if ice_init() fails at any point after calling
ice_init_dev().
Upon errors, ice_init() calls ice_deinit_dev(), which is supposed to be the
inverse of ice_init_dev(). However, currently ice_init_dev() does not call
ice_init_hw(). Instead, ice_init_hw() is called by ice_probe(). Thus,
ice_probe() itself calls ice_deinit_hw() as part of its error cleanup
logic.
This results in two calls to ice_deinit_hw() which results in straight
forward use-after-free violations due to double calling kfree and other
cleanup functions.
To avoid this double call, move the call to ice_init_hw() into
ice_init_dev(), and remove the now logically unnecessary cleanup from
ice_probe(). This is simpler than the alternative of moving ice_deinit_hw()
*out* of ice_deinit_dev().
Moving the calls to ice_deinit_hw() requires validating all cleanup paths,
and changing significantly more code. Moving the calls of ice_init_hw()
requires only validating that the new placement is still prior to all HW
structure accesses.
For ice_probe(), this now delays ice_init_hw() from before
ice_adapter_get() to just after it. This is safe, as ice_adapter_get() does
not rely on the HW structure.
For ice_devlink_reinit_up(), the ice_init_hw() is now called after
ice_set_min_max_msix(). This is also safe as that function does not access
the HW structure either.
This flow makes more logical sense, as ice_init_dev() is mirrored by
ice_deinit_dev(), so it reasonably should be the caller of ice_init_hw().
It also reduces one extra call to ice_init_hw() since both ice_probe() and
ice_devlink_reinit_up() call ice_init_dev().
This resolves the double-free and avoids memory corruption and other
invalid memory accesses in the event of a failed probe.
Fixes: 5b246e5 ("ice: split probe into smaller functions")
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>1 parent 5c4911e commit d49a07a
2 files changed
+12
-22
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1233 | 1233 | | |
1234 | 1234 | | |
1235 | 1235 | | |
1236 | | - | |
1237 | | - | |
1238 | | - | |
1239 | | - | |
1240 | | - | |
1241 | | - | |
1242 | 1236 | | |
1243 | 1237 | | |
1244 | 1238 | | |
1245 | 1239 | | |
1246 | 1240 | | |
1247 | | - | |
| 1241 | + | |
1248 | 1242 | | |
1249 | 1243 | | |
1250 | 1244 | | |
| |||
1267 | 1261 | | |
1268 | 1262 | | |
1269 | 1263 | | |
1270 | | - | |
1271 | | - | |
1272 | 1264 | | |
1273 | 1265 | | |
1274 | 1266 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4743 | 4743 | | |
4744 | 4744 | | |
4745 | 4745 | | |
| 4746 | + | |
| 4747 | + | |
| 4748 | + | |
| 4749 | + | |
| 4750 | + | |
| 4751 | + | |
4746 | 4752 | | |
4747 | 4753 | | |
4748 | 4754 | | |
| |||
4763 | 4769 | | |
4764 | 4770 | | |
4765 | 4771 | | |
4766 | | - | |
| 4772 | + | |
4767 | 4773 | | |
4768 | 4774 | | |
4769 | 4775 | | |
| |||
4806 | 4812 | | |
4807 | 4813 | | |
4808 | 4814 | | |
| 4815 | + | |
| 4816 | + | |
4809 | 4817 | | |
4810 | 4818 | | |
4811 | 4819 | | |
| |||
5333 | 5341 | | |
5334 | 5342 | | |
5335 | 5343 | | |
5336 | | - | |
5337 | | - | |
5338 | | - | |
5339 | | - | |
5340 | | - | |
5341 | | - | |
5342 | 5344 | | |
5343 | | - | |
5344 | | - | |
5345 | | - | |
5346 | | - | |
| 5345 | + | |
| 5346 | + | |
5347 | 5347 | | |
5348 | 5348 | | |
5349 | 5349 | | |
| |||
5369 | 5369 | | |
5370 | 5370 | | |
5371 | 5371 | | |
5372 | | - | |
5373 | | - | |
5374 | 5372 | | |
5375 | 5373 | | |
5376 | 5374 | | |
| |||
0 commit comments