]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
iw: handle positive error codes gracefully
authorBrian Norris <briannorris@chromium.org>
Tue, 3 Nov 2020 23:56:31 +0000 (15:56 -0800)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 6 Nov 2020 08:53:32 +0000 (09:53 +0100)
netlink(7) requires error codes to be negative, but since when does a
man page stop anyone? At a minimum, we shouldn't allow a non-conforming
vendor command to put us into an infinite loop in the below snippets
from __handle_cmd():

err = 1;

nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
...
while (err > 0)
nl_recvmsgs(state->nl_sock, cb);

Signed-off-by: Brian Norris <briannorris@chromium.org>
Link: https://lore.kernel.org/r/20201103235631.2936594-1-briannorris@chromium.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
iw.c

diff --git a/iw.c b/iw.c
index da71617921d8a3c0a8e7c8c05f4e76dcba4987c0..35308ba3244a3750cf71491124b5c74d542dda73 100644 (file)
--- a/iw.c
+++ b/iw.c
@@ -287,7 +287,19 @@ static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
        int *ret = arg;
        int ack_len = sizeof(*nlh) + sizeof(int) + sizeof(*nlh);
 
-       *ret = err->error;
+       if (err->error > 0) {
+               /*
+                * This is illegal, per netlink(7), but not impossible (think
+                * "vendor commands"). Callers really expect negative error
+                * codes, so make that happen.
+                */
+               fprintf(stderr,
+                       "ERROR: received positive netlink error code %d\n",
+                       err->error);
+               *ret = -EPROTO;
+       } else {
+               *ret = err->error;
+       }
 
        if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS))
                return NL_STOP;