* [PATCH] RDMA/irdma: fix double free of close_entry in TIME_WAIT teardown
@ 2026-11-04 2:53 Wentao Liang
2026-11-04 7:10 ` Krzysztof Kozlowski
2026-11-05 15:57 ` sashiko-bot
0 siblings, 2 replies; 3+ messages in thread
From: Wentao Liang @ 2026-11-04 2:53 UTC (permalink / raw)
To: Tatyana Nikolova, Jason Gunthorpe, Leon Romanovsky; +Cc: linux-rdma
irdma_handle_close_entry() drops the cm_node reference held by the close
timer before releasing cm_node->close_entry. If that put is the last
one, irdma_rem_ref_cm_node() runs irdma_destroy_connection(), which
still sees a non-NULL close_entry and calls
irdma_handle_close_entry(cm_node, 0). That nested call frees the
close_entry and clears the pointer, and the outer call then frees the
same object once more.
Free the close_entry and clear cm_node->close_entry before dropping the
reference, so that a release triggered from that put observes a clean
cm_node.
Fixes: 146b9756f14c ("RDMA/irdma: Add connection manager")
Cc: stable@vger.kernel.org
Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
drivers/infiniband/hw/irdma/cm.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
index 91c0e7298283..d8b8939d6abd 100644
--- a/drivers/infiniband/hw/irdma/cm.c
+++ b/drivers/infiniband/hw/irdma/cm.c
@@ -1243,13 +1243,15 @@ static void irdma_handle_close_entry(struct irdma_cm_node *cm_node,
} else {
spin_unlock_irqrestore(&iwqp->lock, flags);
}
- } else if (rem_node) {
- /* TIME_WAIT state */
- irdma_rem_ref_cm_node(cm_node);
}
kfree(close_entry);
cm_node->close_entry = NULL;
+
+ if (!iwqp && rem_node) {
+ /* TIME_WAIT state */
+ irdma_rem_ref_cm_node(cm_node);
+ }
}
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] RDMA/irdma: fix double free of close_entry in TIME_WAIT teardown
2026-11-04 2:53 [PATCH] RDMA/irdma: fix double free of close_entry in TIME_WAIT teardown Wentao Liang
@ 2026-11-04 7:10 ` Krzysztof Kozlowski
2026-11-05 15:57 ` sashiko-bot
1 sibling, 0 replies; 3+ messages in thread
From: Krzysztof Kozlowski @ 2026-11-04 7:10 UTC (permalink / raw)
To: Wentao Liang
Cc: Tatyana Nikolova, linux-rdma, Jason Gunthorpe, Leon Romanovsky
On Wed, 04 Nov 2026 02:53:47 +0000, Wentao Liang wrote:
> irdma_handle_close_entry() drops the cm_node reference held by the close
> timer before releasing cm_node->close_entry. If that put is the last
> one, irdma_rem_ref_cm_node() runs irdma_destroy_connection(), which
> still sees a non-NULL close_entry and calls
> irdma_handle_close_entry(cm_node, 0). That nested call frees the
> close_entry and clears the pointer, and the outer call then frees the
> same object once more.
>
> Free the close_entry and clear cm_node->close_entry before dropping the
> reference, so that a release triggered from that put observes a clean
> cm_node.
>
> Fixes: 146b9756f14c ("RDMA/irdma: Add connection manager")
> Cc: stable@vger.kernel.org
> Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
> ---
> drivers/infiniband/hw/irdma/cm.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
Multiple things here:
1. Your team ignored completely previous feedback. Multiple times.
2. You use multiple identities with this email address, thus I doubt that we
speak with an actual person.
3. Your bot does not even bother running checkpatch, right?
4. Nothing of this was reproduced nor tested.
5. Finally, the same feedback:
You sent multiple independent patches, to multiple independent
subsystems. The amount of these patches clearly suggest this was
AI generated and most likely not tested.
More importantly, you sent all this work without properly organizing
relevant patches into patchsets. This makes reviewing difficult
and might cause multiple reviewers to address the same issue.
Replying to the entire set is impossible and requires handling each
patch independently, instead of applying or discarding the set.
Maintainers also won't see the bigger picture of your work. Quite
worrying.
This is on the verge of hostile patch: bomb us with so many
contributions, we won't be able to handle them in efficient manner,
like responding ONCE to ask you to slow down. Considering all this
is untested and LLM generated, I have even more doubts whether this
should be considered for review.
Please read kernel documentation BEFORE posting more work. It will
explain you how to identify subsystems, how to organize your work per
subsystem (so a patchset grouping multiple patches with a short cover
letter), how to document the issue discovery method and what was
or was not tested.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] RDMA/irdma: fix double free of close_entry in TIME_WAIT teardown
2026-11-04 2:53 [PATCH] RDMA/irdma: fix double free of close_entry in TIME_WAIT teardown Wentao Liang
2026-11-04 7:10 ` Krzysztof Kozlowski
@ 2026-11-05 15:57 ` sashiko-bot
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-11-05 15:57 UTC (permalink / raw)
To: Wentao Liang; +Cc: linux-rdma
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] RDMA/irdma: refcount underflow and UAF in irdma_cm_timer_tick()
--
commit 3abe5e40541e0bcf80a0a51f21ea66e768ed3bae
Author: Wentao Liang <vulab@iscas.ac.cn>
RDMA/irdma: fix double free of close_entry in TIME_WAIT teardown
This commit reorders freeing close_entry and clearing cm_node->close_entry
before calling irdma_rem_ref_cm_node() in irdma_handle_close_entry() to avoid
a double free if dropping the cm_node reference triggers
irdma_destroy_connection().
> diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
> index 91c0e72982836..d8b8939d6abdb 100644
> --- a/drivers/infiniband/hw/irdma/cm.c
> +++ b/drivers/infiniband/hw/irdma/cm.c
> @@ -1243,13 +1243,15 @@ static void irdma_handle_close_entry(struct irdma_cm_node *cm_node,
> } else {
> spin_unlock_irqrestore(&iwqp->lock, flags);
> }
> - } else if (rem_node) {
> - /* TIME_WAIT state */
> - irdma_rem_ref_cm_node(cm_node);
> }
>
> kfree(close_entry);
> cm_node->close_entry = NULL;
> +
> + if (!iwqp && rem_node) {
> + /* TIME_WAIT state */
> + irdma_rem_ref_cm_node(cm_node);
> + }
> }
[Severity: Critical]
If irdma_rem_ref_cm_node(cm_node) here drops the last reference on cm_node,
does the caller irdma_cm_timer_tick() suffer a use-after-free on cm_node and
underflow cm_node->refcnt?
irdma_handle_close_entry() has only two callers: irdma_destroy_connection()
passes rem_node = 0, and irdma_cm_timer_tick() passes rem_node = 1.
Before iterating timer_list, irdma_cm_timer_tick() calls
irdma_timer_list_prep(), which takes a dedicated reference on each queued
cm_node for timer_list:
drivers/infiniband/hw/irdma/cm.c:irdma_timer_list_prep() {
...
if ((cm_node->close_entry || cm_node->send_entry) &&
refcount_inc_not_zero(&cm_node->refcnt))
list_add(&cm_node->timer_entry, timer_list);
...
}
In normal non-racing TIME_WAIT expiration, cm_node->refcnt is at least 2 when
entering irdma_handle_close_entry(cm_node, 1) (one for the connection in
IRDMA_CM_STATE_TIME_WAIT and one for timer_list), so the put in
irdma_handle_close_entry() drops refcnt from 2 to 1 and is not the final put.
The put in irdma_handle_close_entry(cm_node, 1) only becomes the final put
(reducing refcnt from 1 to 0 and calling irdma_destroy_connection()) when a
concurrent FIN or RST packet in irdma_handle_fin_pkt() or
irdma_handle_rst_pkt() processes IRDMA_CM_STATE_TIME_WAIT and drops the
TIME_WAIT reference without clearing cm_node->close_entry while cm_node is on
timer_list (or when irdma_handle_close_entry() drops the TIME_WAIT reference
without changing cm_node->state out of IRDMA_CM_STATE_TIME_WAIT before a
concurrent FIN or RST arrives):
drivers/infiniband/hw/irdma/cm.c:irdma_handle_fin_pkt() {
...
case IRDMA_CM_STATE_TIME_WAIT:
cm_node->tcp_cntxt.rcv_nxt++;
irdma_cleanup_retrans_entry(cm_node);
cm_node->state = IRDMA_CM_STATE_CLOSED;
irdma_rem_ref_cm_node(cm_node);
break;
...
}
drivers/infiniband/hw/irdma/cm.c:irdma_handle_rst_pkt() {
...
case IRDMA_CM_STATE_TIME_WAIT:
cm_node->state = IRDMA_CM_STATE_CLOSED;
irdma_rem_ref_cm_node(cm_node);
break;
...
}
When that happens, irdma_rem_ref_cm_node(cm_node) inside
irdma_handle_close_entry(cm_node, 1) consumes the caller's timer_list
reference, runs irdma_destroy_connection(cm_node), and schedules
kfree_rcu(cm_node, rcu_head). It then returns to irdma_cm_timer_tick(), which
is outside RCU protection and continues using cm_node before dropping the
timer_list reference at done:
drivers/infiniband/hw/irdma/cm.c:irdma_cm_timer_tick() {
...
} else {
irdma_handle_close_entry(cm_node, 1);
}
}
spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
send_entry = cm_node->send_entry;
if (!send_entry)
goto done;
...
done:
spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
irdma_rem_ref_cm_node(cm_node);
}
}
Even with close_entry freed and cleared beforehand, wouldn't
irdma_cm_timer_tick() still access a destroyed cm_node and call
irdma_rem_ref_cm_node(cm_node) again when cm_node->refcnt is already 0?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104025347.1527584-1-vulab@iscas.ac.cn?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-05 15:57 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 2:53 [PATCH] RDMA/irdma: fix double free of close_entry in TIME_WAIT teardown Wentao Liang
2026-11-04 7:10 ` Krzysztof Kozlowski
2026-11-05 15:57 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox