net: lwm2m: handle pending before send in retransmit

When resending data, we need to always check pending status first.
If the pending check returns an "expired" status, avoid sending the
data to L2 network driver entirely.

This change fixes a use after free issue, where the L2 network driver
was still handling a packet that was expired out from under it when
the pending status was checked.

Signed-off-by: Michael Scott <mike@foundries.io>
This commit is contained in:
Michael Scott 2018-09-13 08:52:42 -07:00 committed by Anas Nashif
commit 70b9e7bab6

View file

@ -3634,6 +3634,20 @@ static void retransmit_request(struct k_work *work)
return;
}
if (!coap_pending_cycle(pending)) {
/* pending request has expired */
if (msg->message_timeout_cb) {
msg->message_timeout_cb(msg);
}
/*
* coap_pending_clear() is called in lwm2m_reset_message()
* which balances the ref we made in coap_pending_cycle()
*/
lwm2m_reset_message(msg, true);
return;
}
LOG_DBG("Resending message: %p", msg);
msg->send_attempts++;
/*
@ -3652,20 +3666,6 @@ static void retransmit_request(struct k_work *work)
net_pkt_unref(msg->cpkt.pkt);
}
if (!coap_pending_cycle(pending)) {
/* pending request has expired */
if (msg->message_timeout_cb) {
msg->message_timeout_cb(msg);
}
/*
* coap_pending_clear() is called in lwm2m_reset_message()
* which balances the ref we made in coap_pending_cycle()
*/
lwm2m_reset_message(msg, true);
return;
}
k_delayed_work_submit(&client_ctx->retransmit_work, pending->timeout);
}