summaryrefslogtreecommitdiffstats
path: root/lib/nlattr.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2018-09-17 11:57:29 +0200
committerDavid S. Miller <davem@davemloft.net>2018-09-18 19:51:29 -0700
commitb60b87fc2996240e298529a46e122ef62ef9c27f (patch)
treea39a2b84798368f1c53b412586eff77e6e3b1673 /lib/nlattr.c
parent568b742a9d9888aca876b6ad9fa45490f18bee0a (diff)
downloadlinux-b60b87fc2996240e298529a46e122ef62ef9c27f.tar.gz
linux-b60b87fc2996240e298529a46e122ef62ef9c27f.tar.bz2
linux-b60b87fc2996240e298529a46e122ef62ef9c27f.zip
netlink: add ethernet address policy types
Commonly, ethernet addresses are just using a policy of { .len = ETH_ALEN } which leaves userspace free to send more data than it should, which may hide bugs. Introduce NLA_EXACT_LEN which checks for exact size, rejecting the attribute if it's not exactly that length. Also add NLA_EXACT_LEN_WARN which requires the minimum length and will warn on longer attributes, for backward compatibility. Use these to define NLA_POLICY_ETH_ADDR (new strict policy) and NLA_POLICY_ETH_ADDR_COMPAT (compatible policy with warning); these are used like this: static const struct nla_policy <name>[...] = { [NL_ATTR_NAME] = NLA_POLICY_ETH_ADDR, ... }; Signed-off-by: Johannes Berg <johannes.berg@intel.com> Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib/nlattr.c')
-rw-r--r--lib/nlattr.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/lib/nlattr.c b/lib/nlattr.c
index 36d74b079151..bb6fe5ed4ecf 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -82,12 +82,18 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
BUG_ON(pt->type > NLA_TYPE_MAX);
- if (nla_attr_len[pt->type] && attrlen != nla_attr_len[pt->type]) {
+ if ((nla_attr_len[pt->type] && attrlen != nla_attr_len[pt->type]) ||
+ (pt->type == NLA_EXACT_LEN_WARN && attrlen != pt->len)) {
pr_warn_ratelimited("netlink: '%s': attribute type %d has an invalid length.\n",
current->comm, type);
}
switch (pt->type) {
+ case NLA_EXACT_LEN:
+ if (attrlen != pt->len)
+ return -ERANGE;
+ break;
+
case NLA_REJECT:
if (pt->validation_data && error_msg)
*error_msg = pt->validation_data;