Skip to content

Commit 3d1b5d3

Browse files
karstengrgregkh
authored andcommitted
net/smc: fix use-after-free of delayed events
[ Upstream commit d535ca1 ] When a delayed event is enqueued then the event worker will send this event the next time it is running and no other flow is currently active. The event handler is called for the delayed event, and the pointer to the event keeps set in lgr->delayed_event. This pointer is cleared later in the processing by smc_llc_flow_start(). This can lead to a use-after-free condition when the processing does not reach smc_llc_flow_start(), but frees the event because of an error situation. Then the delayed_event pointer is still set but the event is freed. Fix this by always clearing the delayed event pointer when the event is provided to the event handler for processing, and remove the code to clear it in smc_llc_flow_start(). Fixes: 555da9a ("net/smc: add event-based llc_flow framework") Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent ea4f9b8 commit 3d1b5d3

File tree

1 file changed

+5
-8
lines changed

1 file changed

+5
-8
lines changed

net/smc/smc_llc.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,6 @@ static bool smc_llc_flow_start(struct smc_llc_flow *flow,
233233
default:
234234
flow->type = SMC_LLC_FLOW_NONE;
235235
}
236-
if (qentry == lgr->delayed_event)
237-
lgr->delayed_event = NULL;
238236
smc_llc_flow_qentry_set(flow, qentry);
239237
spin_unlock_bh(&lgr->llc_flow_lock);
240238
return true;
@@ -1603,13 +1601,12 @@ static void smc_llc_event_work(struct work_struct *work)
16031601
struct smc_llc_qentry *qentry;
16041602

16051603
if (!lgr->llc_flow_lcl.type && lgr->delayed_event) {
1606-
if (smc_link_usable(lgr->delayed_event->link)) {
1607-
smc_llc_event_handler(lgr->delayed_event);
1608-
} else {
1609-
qentry = lgr->delayed_event;
1610-
lgr->delayed_event = NULL;
1604+
qentry = lgr->delayed_event;
1605+
lgr->delayed_event = NULL;
1606+
if (smc_link_usable(qentry->link))
1607+
smc_llc_event_handler(qentry);
1608+
else
16111609
kfree(qentry);
1612-
}
16131610
}
16141611

16151612
again:

0 commit comments

Comments
 (0)