From patchwork Wed Sep 19 12:08:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 10605753 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D2BAA161F for ; Wed, 19 Sep 2018 12:09:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C9EB52B62F for ; Wed, 19 Sep 2018 12:09:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BE40E2B63C; Wed, 19 Sep 2018 12:09:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 709192B62F for ; Wed, 19 Sep 2018 12:09:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731471AbeISRqx (ORCPT ); Wed, 19 Sep 2018 13:46:53 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:53222 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731254AbeISRqw (ORCPT ); Wed, 19 Sep 2018 13:46:52 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.91) (envelope-from ) id 1g2bI9-0007lf-3S; Wed, 19 Sep 2018 14:09:13 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 1/7] netlink: remove NLA_NESTED_COMPAT Date: Wed, 19 Sep 2018 14:08:54 +0200 Message-Id: <20180919120900.28708-2-johannes@sipsolutions.net> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180919120900.28708-1-johannes@sipsolutions.net> References: <20180919120900.28708-1-johannes@sipsolutions.net> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Johannes Berg This isn't used anywhere, so we might as well get rid of it. Reviewed-by: David Ahern Signed-off-by: Johannes Berg --- include/net/netlink.h | 2 -- lib/nlattr.c | 11 ----------- 2 files changed, 13 deletions(-) diff --git a/include/net/netlink.h b/include/net/netlink.h index 318b1ded3833..b680fe365e91 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -172,7 +172,6 @@ enum { NLA_FLAG, NLA_MSECS, NLA_NESTED, - NLA_NESTED_COMPAT, NLA_NUL_STRING, NLA_BINARY, NLA_S8, @@ -203,7 +202,6 @@ enum { * NLA_BINARY Maximum length of attribute payload * NLA_NESTED Don't use `len' field -- length verification is * done by checking len of nested header (or empty) - * NLA_NESTED_COMPAT Minimum length of structure payload * NLA_U8, NLA_U16, * NLA_U32, NLA_U64, * NLA_S8, NLA_S16, diff --git a/lib/nlattr.c b/lib/nlattr.c index bb6fe5ed4ecf..120ad569e13d 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -140,17 +140,6 @@ static int validate_nla(const struct nlattr *nla, int maxtype, return -ERANGE; break; - case NLA_NESTED_COMPAT: - if (attrlen < pt->len) - return -ERANGE; - if (attrlen < NLA_ALIGN(pt->len)) - break; - if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN) - return -ERANGE; - nla = nla_data(nla) + NLA_ALIGN(pt->len); - if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla)) - return -ERANGE; - break; case NLA_NESTED: /* a nested attributes is allowed to be empty; if its not, * it must have a size of at least NLA_HDRLEN. From patchwork Wed Sep 19 12:08:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 10605749 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 88792161F for ; Wed, 19 Sep 2018 12:09:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7F3A72B610 for ; Wed, 19 Sep 2018 12:09:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 739692B62F; Wed, 19 Sep 2018 12:09:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 20A5C2B610 for ; Wed, 19 Sep 2018 12:09:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731503AbeISRqx (ORCPT ); Wed, 19 Sep 2018 13:46:53 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:53226 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731399AbeISRqw (ORCPT ); Wed, 19 Sep 2018 13:46:52 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.91) (envelope-from ) id 1g2bI9-0007lf-FD; Wed, 19 Sep 2018 14:09:13 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 2/7] netlink: make validation_data const Date: Wed, 19 Sep 2018 14:08:55 +0200 Message-Id: <20180919120900.28708-3-johannes@sipsolutions.net> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180919120900.28708-1-johannes@sipsolutions.net> References: <20180919120900.28708-1-johannes@sipsolutions.net> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Johannes Berg The validation data is only used within the policy that should usually already be const, and isn't changed in any code that uses it. Therefore, make the validation_data pointer const. While at it, remove the duplicate variable in the bitfield validation that I'd otherwise have to change to const. Signed-off-by: Johannes Berg Reviewed-by: David Ahern --- include/net/netlink.h | 2 +- lib/nlattr.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/net/netlink.h b/include/net/netlink.h index b680fe365e91..0d698215d4d9 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -237,7 +237,7 @@ enum { struct nla_policy { u16 type; u16 len; - void *validation_data; + const void *validation_data; }; #define NLA_POLICY_EXACT_LEN(_len) { .type = NLA_EXACT_LEN, .len = _len } diff --git a/lib/nlattr.c b/lib/nlattr.c index 120ad569e13d..e2e5b38394d5 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -45,12 +45,11 @@ static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = { }; static int validate_nla_bitfield32(const struct nlattr *nla, - u32 *valid_flags_allowed) + const u32 *valid_flags_mask) { const struct nla_bitfield32 *bf = nla_data(nla); - u32 *valid_flags_mask = valid_flags_allowed; - if (!valid_flags_allowed) + if (!valid_flags_mask) return -EINVAL; /*disallow invalid bit selector */ From patchwork Wed Sep 19 12:08:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 10605755 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 017D1161F for ; Wed, 19 Sep 2018 12:09:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EC5722B62F for ; Wed, 19 Sep 2018 12:09:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E0F972B63C; Wed, 19 Sep 2018 12:09:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9CA1D2B62F for ; Wed, 19 Sep 2018 12:09:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731580AbeISRrL (ORCPT ); Wed, 19 Sep 2018 13:47:11 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:53230 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727772AbeISRqx (ORCPT ); Wed, 19 Sep 2018 13:46:53 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.91) (envelope-from ) id 1g2bI9-0007lf-Rh; Wed, 19 Sep 2018 14:09:14 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 3/7] netlink: set extack error message in nla_validate() Date: Wed, 19 Sep 2018 14:08:56 +0200 Message-Id: <20180919120900.28708-4-johannes@sipsolutions.net> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180919120900.28708-1-johannes@sipsolutions.net> References: <20180919120900.28708-1-johannes@sipsolutions.net> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Johannes Berg In nla_parse() we already set this, but it makes sense to also do it in nla_validate() which already also sets the bad attribute pointer. CC: David Ahern Signed-off-by: Johannes Berg --- lib/nlattr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/nlattr.c b/lib/nlattr.c index e2e5b38394d5..33404745bec4 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -180,9 +180,13 @@ int nla_validate(const struct nlattr *head, int len, int maxtype, int rem; nla_for_each_attr(nla, head, len, rem) { - int err = validate_nla(nla, maxtype, policy, NULL); + static const char _msg[] = "Attribute failed policy validation"; + const char *msg = _msg; + int err = validate_nla(nla, maxtype, policy, &msg); if (err < 0) { + if (extack) + extack->_msg = msg; NL_SET_BAD_ATTR(extack, nla); return err; } From patchwork Wed Sep 19 12:08:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 10605751 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 14615161F for ; Wed, 19 Sep 2018 12:09:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0BBBA2B610 for ; Wed, 19 Sep 2018 12:09:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0005C2B62F; Wed, 19 Sep 2018 12:09:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 78CFB2B610 for ; Wed, 19 Sep 2018 12:09:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731504AbeISRrE (ORCPT ); Wed, 19 Sep 2018 13:47:04 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:53234 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731436AbeISRqx (ORCPT ); Wed, 19 Sep 2018 13:46:53 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.91) (envelope-from ) id 1g2bIA-0007lf-81; Wed, 19 Sep 2018 14:09:14 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 4/7] netlink: combine validate/parse functions Date: Wed, 19 Sep 2018 14:08:57 +0200 Message-Id: <20180919120900.28708-5-johannes@sipsolutions.net> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180919120900.28708-1-johannes@sipsolutions.net> References: <20180919120900.28708-1-johannes@sipsolutions.net> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Johannes Berg The parse function of course contains validate, but it's implemented a second time, sharing just the validation of a single attribute. Introduce nla_validate_parse() that can be used for both parsing/validation and only validation, to share code. Signed-off-by: Johannes Berg --- lib/nlattr.c | 76 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/lib/nlattr.c b/lib/nlattr.c index 33404745bec4..966cd3dcf31b 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -158,6 +158,37 @@ static int validate_nla(const struct nlattr *nla, int maxtype, return 0; } +static int nla_validate_parse(const struct nlattr *head, int len, int maxtype, + const struct nla_policy *policy, + struct netlink_ext_ack *extack, + struct nlattr **tb) +{ + const struct nlattr *nla; + int rem; + + nla_for_each_attr(nla, head, len, rem) { + static const char _msg[] = "Attribute failed policy validation"; + const char *msg = _msg; + u16 type = nla_type(nla); + + if (policy) { + int err = validate_nla(nla, maxtype, policy, &msg); + + if (err < 0) { + if (extack) + extack->_msg = msg; + NL_SET_BAD_ATTR(extack, nla); + return err; + } + } + + if (tb && type > 0 && type <= maxtype) + tb[type] = (struct nlattr *)nla; + } + + return rem; +} + /** * nla_validate - Validate a stream of attributes * @head: head of attribute stream @@ -176,21 +207,12 @@ int nla_validate(const struct nlattr *head, int len, int maxtype, const struct nla_policy *policy, struct netlink_ext_ack *extack) { - const struct nlattr *nla; int rem; - nla_for_each_attr(nla, head, len, rem) { - static const char _msg[] = "Attribute failed policy validation"; - const char *msg = _msg; - int err = validate_nla(nla, maxtype, policy, &msg); + rem = nla_validate_parse(head, len, maxtype, policy, extack, NULL); - if (err < 0) { - if (extack) - extack->_msg = msg; - NL_SET_BAD_ATTR(extack, nla); - return err; - } - } + if (rem < 0) + return rem; return 0; } @@ -244,39 +266,19 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, int len, const struct nla_policy *policy, struct netlink_ext_ack *extack) { - const struct nlattr *nla; - int rem, err; + int rem; memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); - nla_for_each_attr(nla, head, len, rem) { - u16 type = nla_type(nla); - - if (type > 0 && type <= maxtype) { - static const char _msg[] = "Attribute failed policy validation"; - const char *msg = _msg; - - if (policy) { - err = validate_nla(nla, maxtype, policy, &msg); - if (err < 0) { - NL_SET_BAD_ATTR(extack, nla); - if (extack) - extack->_msg = msg; - goto errout; - } - } - - tb[type] = (struct nlattr *)nla; - } - } + rem = nla_validate_parse(head, len, maxtype, policy, extack, tb); + if (rem < 0) + return rem; if (unlikely(rem > 0)) pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n", rem, current->comm); - err = 0; -errout: - return err; + return 0; } EXPORT_SYMBOL(nla_parse); From patchwork Wed Sep 19 12:08:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 10605745 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9C259913 for ; Wed, 19 Sep 2018 12:09:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 927B52B610 for ; Wed, 19 Sep 2018 12:09:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 86A442B62F; Wed, 19 Sep 2018 12:09:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 23F5F2B624 for ; Wed, 19 Sep 2018 12:09:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731555AbeISRqz (ORCPT ); Wed, 19 Sep 2018 13:46:55 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:53238 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731439AbeISRqy (ORCPT ); Wed, 19 Sep 2018 13:46:54 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.91) (envelope-from ) id 1g2bIA-0007lf-LY; Wed, 19 Sep 2018 14:09:14 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 5/7] netlink: prepare validate extack setting for recursion Date: Wed, 19 Sep 2018 14:08:58 +0200 Message-Id: <20180919120900.28708-6-johannes@sipsolutions.net> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180919120900.28708-1-johannes@sipsolutions.net> References: <20180919120900.28708-1-johannes@sipsolutions.net> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Johannes Berg In one of my previous patches in this area I introduced code to pass out just the error message to store in the extack, for use in NLA_REJECT. Change this code now to set both the error message and the bad attribute pointer, and carry around a boolean indicating that the values have been set. This will be used in the next patch to allow recursive validation of nested policies, while preserving the innermost error message rather than overwriting it with a generic out-level message. Note that this is a completely local change - code calling one of nla_parse/nla_validate isn't affected, both functions continue to overwrite any previously set message with an error generated here, but in the next patch the message generated may come from an inner call to nested attribute validation instead, and there the outer (generic) message shouldn't overwrite the inner. Signed-off-by: Johannes Berg --- lib/nlattr.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/nlattr.c b/lib/nlattr.c index 966cd3dcf31b..2b015e43b725 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -69,7 +69,7 @@ static int validate_nla_bitfield32(const struct nlattr *nla, static int validate_nla(const struct nlattr *nla, int maxtype, const struct nla_policy *policy, - const char **error_msg) + struct netlink_ext_ack *extack, bool *extack_set) { const struct nla_policy *pt; int minlen = 0, attrlen = nla_len(nla), type = nla_type(nla); @@ -94,8 +94,11 @@ static int validate_nla(const struct nlattr *nla, int maxtype, break; case NLA_REJECT: - if (pt->validation_data && error_msg) - *error_msg = pt->validation_data; + if (pt->validation_data && extack && !*extack_set) { + *extack_set = true; + extack->_msg = pt->validation_data; + NL_SET_BAD_ATTR(extack, nla); + } return -EINVAL; case NLA_FLAG: @@ -160,24 +163,25 @@ static int validate_nla(const struct nlattr *nla, int maxtype, static int nla_validate_parse(const struct nlattr *head, int len, int maxtype, const struct nla_policy *policy, - struct netlink_ext_ack *extack, + struct netlink_ext_ack *extack, bool *extack_set, struct nlattr **tb) { const struct nlattr *nla; int rem; nla_for_each_attr(nla, head, len, rem) { - static const char _msg[] = "Attribute failed policy validation"; - const char *msg = _msg; u16 type = nla_type(nla); if (policy) { - int err = validate_nla(nla, maxtype, policy, &msg); + int err = validate_nla(nla, maxtype, policy, + extack, extack_set); if (err < 0) { - if (extack) - extack->_msg = msg; - NL_SET_BAD_ATTR(extack, nla); + if (!*extack_set) { + *extack_set = true; + NL_SET_ERR_MSG_ATTR(extack, nla, + "Attribute failed policy validation"); + } return err; } } @@ -207,9 +211,11 @@ int nla_validate(const struct nlattr *head, int len, int maxtype, const struct nla_policy *policy, struct netlink_ext_ack *extack) { + bool extack_set = false; int rem; - rem = nla_validate_parse(head, len, maxtype, policy, extack, NULL); + rem = nla_validate_parse(head, len, maxtype, policy, + extack, &extack_set, NULL); if (rem < 0) return rem; @@ -266,11 +272,13 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, int len, const struct nla_policy *policy, struct netlink_ext_ack *extack) { + bool extack_set = false; int rem; memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); - rem = nla_validate_parse(head, len, maxtype, policy, extack, tb); + rem = nla_validate_parse(head, len, maxtype, policy, + extack, &extack_set, tb); if (rem < 0) return rem; From patchwork Wed Sep 19 12:08:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 10605747 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4E6BD913 for ; Wed, 19 Sep 2018 12:09:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 455C22B610 for ; Wed, 19 Sep 2018 12:09:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3971E2B62F; Wed, 19 Sep 2018 12:09:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CD0DD2B610 for ; Wed, 19 Sep 2018 12:09:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731543AbeISRqz (ORCPT ); Wed, 19 Sep 2018 13:46:55 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:53242 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731442AbeISRqy (ORCPT ); Wed, 19 Sep 2018 13:46:54 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.91) (envelope-from ) id 1g2bIB-0007lf-2T; Wed, 19 Sep 2018 14:09:15 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 6/7] netlink: allow NLA_NESTED to specify nested policy to validate Date: Wed, 19 Sep 2018 14:08:59 +0200 Message-Id: <20180919120900.28708-7-johannes@sipsolutions.net> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180919120900.28708-1-johannes@sipsolutions.net> References: <20180919120900.28708-1-johannes@sipsolutions.net> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Johannes Berg Now that we have a validation_data pointer, and the len field in the policy is unused for NLA_NESTED, we can allow using them both to have nested validation. This can be nice in code, although we still have to use nla_parse_nested() or similar which would also take a policy; however, it also serves as documentation in the policy without requiring a look at the code. Signed-off-by: Johannes Berg --- include/net/netlink.h | 13 +++++++++++-- lib/nlattr.c | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/include/net/netlink.h b/include/net/netlink.h index 0d698215d4d9..91907852da1c 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -200,8 +200,10 @@ enum { * NLA_NUL_STRING Maximum length of string (excluding NUL) * NLA_FLAG Unused * NLA_BINARY Maximum length of attribute payload - * NLA_NESTED Don't use `len' field -- length verification is - * done by checking len of nested header (or empty) + * NLA_NESTED Length verification is done by checking len of + * nested header (or empty); len field is used if + * validation_data is also used, for the max attr + * number in the nested policy. * NLA_U8, NLA_U16, * NLA_U32, NLA_U64, * NLA_S8, NLA_S16, @@ -224,6 +226,10 @@ enum { * NLA_REJECT This attribute is always rejected and validation data * may point to a string to report as the error instead * of the generic one in extended ACK. + * NLA_NESTED Points to a nested policy to validate, must also set + * `len' to the max attribute number. + * Note that nla_parse() will validate, but of course not + * parse, the nested sub-policies. * All other Unused * * Example: @@ -247,6 +253,9 @@ struct nla_policy { #define NLA_POLICY_ETH_ADDR NLA_POLICY_EXACT_LEN(ETH_ALEN) #define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN) +#define NLA_POLICY_NESTED(maxattr, policy) \ + { .type = NLA_NESTED, .validation_data = policy, .len = maxattr } + /** * struct nl_info - netlink source information * @nlh: Netlink message header of original request diff --git a/lib/nlattr.c b/lib/nlattr.c index 2b015e43b725..c0ea8a78eda6 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -67,6 +67,11 @@ static int validate_nla_bitfield32(const struct nlattr *nla, return 0; } +static int nla_validate_parse(const struct nlattr *head, int len, int maxtype, + const struct nla_policy *policy, + struct netlink_ext_ack *extack, bool *extack_set, + struct nlattr **tb); + static int validate_nla(const struct nlattr *nla, int maxtype, const struct nla_policy *policy, struct netlink_ext_ack *extack, bool *extack_set) @@ -148,6 +153,18 @@ static int validate_nla(const struct nlattr *nla, int maxtype, */ if (attrlen == 0) break; + if (attrlen < NLA_HDRLEN) + return -ERANGE; + if (pt->validation_data) { + int err; + + err = nla_validate_parse(nla_data(nla), nla_len(nla), + pt->len, pt->validation_data, + extack, extack_set, NULL); + if (err < 0) + return err; + } + break; default: if (pt->len) minlen = pt->len; From patchwork Wed Sep 19 12:09:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 10605743 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD7D4161F for ; Wed, 19 Sep 2018 12:09:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C13572B624 for ; Wed, 19 Sep 2018 12:09:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B323E2B632; Wed, 19 Sep 2018 12:09:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 14F972B624 for ; Wed, 19 Sep 2018 12:09:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731571AbeISRq4 (ORCPT ); Wed, 19 Sep 2018 13:46:56 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:53246 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731478AbeISRqz (ORCPT ); Wed, 19 Sep 2018 13:46:55 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.91) (envelope-from ) id 1g2bIB-0007lf-F8; Wed, 19 Sep 2018 14:09:15 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org Cc: Johannes Berg Subject: [PATCH 7/7] netlink: add nested array policy validation Date: Wed, 19 Sep 2018 14:09:00 +0200 Message-Id: <20180919120900.28708-8-johannes@sipsolutions.net> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180919120900.28708-1-johannes@sipsolutions.net> References: <20180919120900.28708-1-johannes@sipsolutions.net> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Johannes Berg Sometimes nested netlink attributes are just used as arrays, with the nla_type() of each not being used; we have this in nl80211 and e.g. NFTA_SET_ELEM_LIST_ELEMENTS. Add the ability to validate this type of message directly in the policy, by adding the type NLA_NESTED_ARRAY which does exactly this: require a first level of nesting but ignore the attribute type, and then inside each require a second level of nested and validate those attributes against a given policy (if present). Note that some nested array types actually require that all of the entries have the same index, this is possible to express in a nested policy already, apart from the validation that only the one allowed type is used. Signed-off-by: Johannes Berg --- include/net/netlink.h | 12 +++++++++++- lib/nlattr.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/include/net/netlink.h b/include/net/netlink.h index 91907852da1c..3698ca8ff92c 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -172,6 +172,7 @@ enum { NLA_FLAG, NLA_MSECS, NLA_NESTED, + NLA_NESTED_ARRAY, NLA_NUL_STRING, NLA_BINARY, NLA_S8, @@ -200,7 +201,8 @@ enum { * NLA_NUL_STRING Maximum length of string (excluding NUL) * NLA_FLAG Unused * NLA_BINARY Maximum length of attribute payload - * NLA_NESTED Length verification is done by checking len of + * NLA_NESTED, + * NLA_NESTED_ARRAY Length verification is done by checking len of * nested header (or empty); len field is used if * validation_data is also used, for the max attr * number in the nested policy. @@ -230,6 +232,12 @@ enum { * `len' to the max attribute number. * Note that nla_parse() will validate, but of course not * parse, the nested sub-policies. + * NLA_NESTED_ARRAY Points to a nested policy to validate, must also set + * `len' to the max attribute number. The difference to + * NLA_NESTED is the structure - NLA_NESTED has the + * nested attributes directly inside, while an array has + * the nested attributes at another level down and the + * attributes directly in the nesting don't matter. * All other Unused * * Example: @@ -255,6 +263,8 @@ struct nla_policy { #define NLA_POLICY_NESTED(maxattr, policy) \ { .type = NLA_NESTED, .validation_data = policy, .len = maxattr } +#define NLA_POLICY_NESTED_ARRAY(maxattr, policy) \ + { .type = NLA_NESTED_ARRAY, .validation_data = policy, .len = maxattr } /** * struct nl_info - netlink source information diff --git a/lib/nlattr.c b/lib/nlattr.c index c0ea8a78eda6..234763b41ab7 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -72,6 +72,35 @@ static int nla_validate_parse(const struct nlattr *head, int len, int maxtype, struct netlink_ext_ack *extack, bool *extack_set, struct nlattr **tb); +static int nla_validate_array(const struct nlattr *head, int len, int maxtype, + const struct nla_policy *policy, + struct netlink_ext_ack *extack, bool *extack_set) +{ + const struct nlattr *entry; + int rem; + + nla_for_each_attr(entry, head, len, rem) { + int ret; + + if (nla_len(entry) == 0) + continue; + + if (nla_len(entry) < NLA_HDRLEN) { + NL_SET_ERR_MSG_ATTR(extack, entry, + "Array element too short"); + return -ERANGE; + } + + ret = nla_validate_parse(nla_data(entry), nla_len(entry), + maxtype, policy, extack, extack_set, + NULL); + if (ret < 0) + return ret; + } + + return 0; +} + static int validate_nla(const struct nlattr *nla, int maxtype, const struct nla_policy *policy, struct netlink_ext_ack *extack, bool *extack_set) @@ -165,6 +194,24 @@ static int validate_nla(const struct nlattr *nla, int maxtype, return err; } break; + case NLA_NESTED_ARRAY: + /* a nested array attribute is allowed to be empty; if its not, + * it must have a size of at least NLA_HDRLEN. + */ + if (attrlen == 0) + break; + if (attrlen < NLA_HDRLEN) + return -ERANGE; + if (pt->validation_data) { + int err; + + err = nla_validate_array(nla_data(nla), nla_len(nla), + pt->len, pt->validation_data, + extack, extack_set); + if (err < 0) + return err; + } + break; default: if (pt->len) minlen = pt->len;