Overview
About vulnerability
In the Linux kernel, the following vulnerability has been resolved:
soc: fsl: qbman: fix race condition in qman_destroy_fq
When QMAN_FQ_FLAG_DYNAMIC_FQID is set, there’s a race condition between fq_table[fq->idx] state and freeing/allocating from the pool and WARN_ON(fq_table[fq->idx]) in qman_create_fq() gets triggered.
Indeed, we can have: Thread A Thread B qman_destroy_fq() qman_create_fq() qman_release_fqid() qman_shutdown_fq() gen_pool_free() – At this point, the fqid is available again – qman_alloc_fqid() – so, we can get the just-freed fqid in thread B – fq->fqid = fqid; fq->idx = fqid * 2; WARN_ON(fq_table[fq->idx]); fq_table[fq->idx] = fq; fq_table[fq->idx] = NULL;
And adding some logs between qman_release_fqid() and fq_table[fq->idx] = NULL makes the WARN_ON() trigger a lot more.
To prevent that, ensure that fq_table[fq->idx] is set to NULL before gen_pool_free() is called by using smp_wmb().
Details
- Affected product:
- AlmaLinux 9.2 ESU , CentOS 8.4 ELS , CentOS 8.5 ELS , CentOS Stream 8 ELS , Oracle Linux 7 ELS , TuxCare 9.6 ESU , Ubuntu 16.04 ELS , Ubuntu 18.04 ELS , Ubuntu 20.04 ELS
- Affected packages:
- linux @ 4.15.0 (+8 more)
In the Linux kernel, the following vulnerability has been resolved:
soc: fsl: qbman: fix race condition in qman_destroy_fq
When QMAN_FQ_FLAG_DYNAMIC_FQID is set, there’s a race condition between fq_table[fq->idx] state and freeing/allocating from the pool and WARN_ON(fq_table[fq->idx]) in qman_create_fq() gets triggered.
Indeed, we can have: Thread A Thread B qman_destroy_fq() qman_create_fq() qman_release_fqid() qman_shutdown_fq() gen_pool_free() – At this point, the fqid is available again – qman_alloc_fqid() – so, we can get the just-freed fqid in thread B – fq->fqid = fqid; fq->idx = fqid * 2; WARN_ON(fq_table[fq->idx]); fq_table[fq->idx] = fq; fq_table[fq->idx] = NULL;
And adding some logs between qman_release_fqid() and fq_table[fq->idx] = NULL makes the WARN_ON() trigger a lot more.
To prevent that, ensure that fq_table[fq->idx] is set to NULL before gen_pool_free() is called by using smp_wmb().