lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190321220504.7642-2-johannes@sipsolutions.net>
Date:   Thu, 21 Mar 2019 23:04:59 +0100
From:   Johannes Berg <johannes@...solutions.net>
To:     netdev@...r.kernel.org
Cc:     David Ahern <dsa@...ulusnetworks.com>,
        Johannes Berg <johannes.berg@...el.com>
Subject: [RFC 1/6] netlink: add nlmsg_validate_strict() & nla_validate_strict()

From: Johannes Berg <johannes.berg@...el.com>

These are needed since we want to separate validation and parsing
in some cases, e.g. in generic netlink to ensure that dump messages
are valid, but we don't typically parse them.

Signed-off-by: Johannes Berg <johannes.berg@...el.com>
---
 include/net/netlink.h | 26 +++++++++++++++++++++++++
 lib/nlattr.c          | 45 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/include/net/netlink.h b/include/net/netlink.h
index 23f27b0b3cef..e211b745008a 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -66,6 +66,7 @@
  *   nlmsg_find_attr()			find an attribute in a message
  *   nlmsg_for_each_msg()		loop over all messages
  *   nlmsg_validate()			validate netlink message incl. attrs
+ *   nlmsg_validate_strict()		strictly validate netlink message/attrs
  *   nlmsg_for_each_attr()		loop over all attributes
  *
  * Misc:
@@ -149,6 +150,7 @@
  *   nla_ok(nla, remaining)		does nla fit into remaining bytes?
  *   nla_next(nla, remaining)		get next netlink attribute
  *   nla_validate()			validate a stream of attributes
+ *   nla_validate_strict()		strictly validate a stream of attributes
  *   nla_validate_nested()		validate a stream of nested attributes
  *   nla_find()				find attribute in stream of attributes
  *   nla_find_nested()			find attribute in nested attributes
@@ -374,6 +376,9 @@ int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid,
 int nla_validate(const struct nlattr *head, int len, int maxtype,
 		 const struct nla_policy *policy,
 		 struct netlink_ext_ack *extack);
+int nla_validate_strict(const struct nlattr *head, int len, int maxtype,
+			const struct nla_policy *policy,
+			struct netlink_ext_ack *extack);
 int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
 	      int len, const struct nla_policy *policy,
 	      struct netlink_ext_ack *extack);
@@ -582,6 +587,27 @@ static inline int nlmsg_validate(const struct nlmsghdr *nlh,
 			    extack);
 }
 
+/**
+ * nlmsg_validate_strict - strictly validate a netlink message including attrs
+ * @nlh: netlinket message header
+ * @hdrlen: length of familiy specific header
+ * @maxtype: maximum attribute type to be expected
+ * @policy: validation policy
+ * @extack: extended ACK report struct
+ */
+static inline int nlmsg_validate_strict(const struct nlmsghdr *nlh,
+					int hdrlen, int maxtype,
+					const struct nla_policy *policy,
+					struct netlink_ext_ack *extack)
+{
+	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
+		return -EINVAL;
+
+	return nla_validate_strict(nlmsg_attrdata(nlh, hdrlen),
+				   nlmsg_attrlen(nlh, hdrlen), maxtype,
+				   policy, extack);
+}
+
 /**
  * nlmsg_report - need to report back to application?
  * @nlh: netlink message header
diff --git a/lib/nlattr.c b/lib/nlattr.c
index d26de6156b97..3ccef39b89de 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -347,6 +347,51 @@ int nla_validate(const struct nlattr *head, int len, int maxtype,
 }
 EXPORT_SYMBOL(nla_validate);
 
+/**
+ * nla_validate_strict - Strictly validate a stream of attributes
+ * @head: head of attribute stream
+ * @len: length of attribute stream
+ * @maxtype: maximum attribute type to be expected
+ * @policy: validation policy
+ * @extack: extended ACK report struct
+ *
+ * Validates all attributes in the specified attribute stream against the
+ * specified policy. Attributes with a type exceeding maxtype will be
+ * ignored. See documenation of struct nla_policy for more details.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int nla_validate_strict(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) {
+		u16 type = nla_type(nla);
+		int err;
+
+		if (type == 0 || type > maxtype) {
+			NL_SET_ERR_MSG(extack, "Unknown attribute type");
+			return -EINVAL;
+		}
+
+		err = validate_nla(nla, maxtype, policy, extack);
+
+		if (err < 0)
+			return err;
+	}
+
+	if (unlikely(rem > 0)) {
+		NL_SET_ERR_MSG(extack, "bytes leftover after parsing attributes");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(nla_validate_strict);
+
 /**
  * nla_policy_len - Determin the max. length of a policy
  * @policy: policy to use
-- 
2.17.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ