diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-11-05 11:49:49 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-11-05 11:49:49 +0100 |
commit | 54ef6c09116430e5ce35777bd899f750d84e4dc1 (patch) | |
tree | 2eaf22a03077dd46f27830b0c77c25d9e814b0d5 /lib | |
parent | e6efadbf0c896da5a49808d733c2c6a59c5a854f (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.c | 11 |
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); |