| From fa72728c052a5f97ed432f66007654926cef4cb1 Mon Sep 17 00:00:00 2001 |
| From: Brian Norris <briannorris@chromium.org> |
| Date: Tue, 3 Nov 2020 15:56:31 -0800 |
| Subject: [PATCH] iw: handle positive error codes gracefully |
| |
| 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 | 14 +++++++++++++- |
| 1 file changed, 13 insertions(+), 1 deletion(-) |
| |
| diff --git a/iw.c b/iw.c |
| index da71617921d8..35308ba3244a 100644 |
| --- 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; |
| -- |
| 2.30.0.365.g02bc693789-goog |
| |