CVE-2022-50174
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
18/06/2025
Last modified:
18/06/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net: hinic: avoid kernel hung in hinic_get_stats64()<br />
<br />
When using hinic device as a bond slave device, and reading device stats<br />
of master bond device, the kernel may hung.<br />
<br />
The kernel panic calltrace as follows:<br />
Kernel panic - not syncing: softlockup: hung tasks<br />
Call trace:<br />
native_queued_spin_lock_slowpath+0x1ec/0x31c<br />
dev_get_stats+0x60/0xcc<br />
dev_seq_printf_stats+0x40/0x120<br />
dev_seq_show+0x1c/0x40<br />
seq_read_iter+0x3c8/0x4dc<br />
seq_read+0xe0/0x130<br />
proc_reg_read+0xa8/0xe0<br />
vfs_read+0xb0/0x1d4<br />
ksys_read+0x70/0xfc<br />
__arm64_sys_read+0x20/0x30<br />
el0_svc_common+0x88/0x234<br />
do_el0_svc+0x2c/0x90<br />
el0_svc+0x1c/0x30<br />
el0_sync_handler+0xa8/0xb0<br />
el0_sync+0x148/0x180<br />
<br />
And the calltrace of task that actually caused kernel hungs as follows:<br />
__switch_to+124<br />
__schedule+548<br />
schedule+72<br />
schedule_timeout+348<br />
__down_common+188<br />
__down+24<br />
down+104<br />
hinic_get_stats64+44 [hinic]<br />
dev_get_stats+92<br />
bond_get_stats+172 [bonding]<br />
dev_get_stats+92<br />
dev_seq_printf_stats+60<br />
dev_seq_show+24<br />
seq_read_iter+964<br />
seq_read+220<br />
proc_reg_read+164<br />
vfs_read+172<br />
ksys_read+108<br />
__arm64_sys_read+28<br />
el0_svc_common+132<br />
do_el0_svc+40<br />
el0_svc+24<br />
el0_sync_handler+164<br />
el0_sync+324<br />
<br />
When getting device stats from bond, kernel will call bond_get_stats().<br />
It first holds the spinlock bond->stats_lock, and then call<br />
hinic_get_stats64() to collect hinic device&#39;s stats.<br />
However, hinic_get_stats64() calls `down(&nic_dev->mgmt_lock)` to<br />
protect its critical section, which may schedule current task out.<br />
And if system is under high pressure, the task cannot be woken up<br />
immediately, which eventually triggers kernel hung panic.<br />
<br />
Since previous patch has replaced hinic_dev.tx_stats/rx_stats with local<br />
variable in hinic_get_stats64(), there is nothing need to be protected<br />
by lock, so just removing down()/up() is ok.
Impact
References to Advisories, Solutions, and Tools
- https://git.kernel.org/stable/c/3ba59bbe4f306bb6ee15753db0a40564c0eb7909
- https://git.kernel.org/stable/c/693f31dc91568e61047fd2980a8235e856cd9ce8
- https://git.kernel.org/stable/c/98f9fcdee35add80505b6c73f72de5f750d5c03c
- https://git.kernel.org/stable/c/e74f3097a9c713ce855cda07713393bcc23a005d
- https://git.kernel.org/stable/c/fced5bce712122654ec8a20356342698cce104d2