summaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-11-05 11:49:49 +0100
committerJo-Philipp Wich <jo@mein.io>2021-11-05 11:49:49 +0100
commit54ef6c09116430e5ce35777bd899f750d84e4dc1 (patch)
tree2eaf22a03077dd46f27830b0c77c25d9e814b0d5 /lib
parente6efadbf0c896da5a49808d733c2c6a59c5a854f (diff)
nl80211: fix premature netlink reply receive abort
The nl_recvmsgs() logic in uc_nl_request() incorrectly stopped reading the socket before the netlink ACK message was handled for non-multipart replies. This caused subsequent requests to incorrectly receive the ACK of the previous request, leading to a failure to receive the actual reply. Fix this issue by continue reading the socket until either the finish callback for multipart (dump) messages or the ack callback for non- multipart messages was received. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'lib')
-rw-r--r--lib/nl80211.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/lib/nl80211.c b/lib/nl80211.c
index 45c2bf4..b48ff2a 100644
--- a/lib/nl80211.c
+++ b/lib/nl80211.c
@@ -1961,10 +1961,7 @@ cb_reply(struct nl_msg *msg, void *arg)
ucv_put(o);
}
- if (hdr->nlmsg_flags & NLM_F_MULTI)
- s->state = STATE_CONTINUE;
- else
- s->state = STATE_REPLIED;
+ s->state = STATE_CONTINUE;
return NL_SKIP;
}
@@ -2281,7 +2278,7 @@ uc_nl_waitfor(uc_vm_t *vm, size_t nargs)
static uc_value_t *
uc_nl_request(uc_vm_t *vm, size_t nargs)
{
- request_state_t st = { .vm = vm, .state = STATE_CONTINUE };
+ request_state_t st = { .vm = vm };
uc_value_t *cmd = uc_fn_arg(0);
uc_value_t *flags = uc_fn_arg(1);
uc_value_t *payload = uc_fn_arg(2);
@@ -2340,12 +2337,12 @@ uc_nl_request(uc_vm_t *vm, size_t nargs)
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_reply, &st);
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &st);
- nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_ack, &ret);
+ nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_done, &st);
nl_cb_err(cb, NL_CB_CUSTOM, cb_errno, &ret);
nl_send_auto_complete(nl80211_conn.sock, msg);
- while (ret > 0 && st.state == STATE_CONTINUE)
+ while (ret > 0 && st.state < STATE_REPLIED)
nl_recvmsgs(nl80211_conn.sock, cb);
nlmsg_free(msg);