Commit b60b87fc authored by Johannes Berg's avatar Johannes Berg Committed by David S. Miller

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: default avatarJohannes Berg <johannes.berg@intel.com>
Reviewed-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 568b742a
...@@ -181,6 +181,8 @@ enum { ...@@ -181,6 +181,8 @@ enum {
NLA_S64, NLA_S64,
NLA_BITFIELD32, NLA_BITFIELD32,
NLA_REJECT, NLA_REJECT,
NLA_EXACT_LEN,
NLA_EXACT_LEN_WARN,
__NLA_TYPE_MAX, __NLA_TYPE_MAX,
}; };
...@@ -211,6 +213,10 @@ enum { ...@@ -211,6 +213,10 @@ enum {
* just like "All other" * just like "All other"
* NLA_BITFIELD32 Unused * NLA_BITFIELD32 Unused
* NLA_REJECT Unused * NLA_REJECT Unused
* NLA_EXACT_LEN Attribute must have exactly this length, otherwise
* it is rejected.
* NLA_EXACT_LEN_WARN Attribute should have exactly this length, a warning
* is logged if it is longer, shorter is rejected.
* All other Minimum length of attribute payload * All other Minimum length of attribute payload
* *
* Meaning of `validation_data' field: * Meaning of `validation_data' field:
...@@ -236,6 +242,13 @@ struct nla_policy { ...@@ -236,6 +242,13 @@ struct nla_policy {
void *validation_data; void *validation_data;
}; };
#define NLA_POLICY_EXACT_LEN(_len) { .type = NLA_EXACT_LEN, .len = _len }
#define NLA_POLICY_EXACT_LEN_WARN(_len) { .type = NLA_EXACT_LEN_WARN, \
.len = _len }
#define NLA_POLICY_ETH_ADDR NLA_POLICY_EXACT_LEN(ETH_ALEN)
#define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN)
/** /**
* struct nl_info - netlink source information * struct nl_info - netlink source information
* @nlh: Netlink message header of original request * @nlh: Netlink message header of original request
......
...@@ -82,12 +82,18 @@ static int validate_nla(const struct nlattr *nla, int maxtype, ...@@ -82,12 +82,18 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
BUG_ON(pt->type > NLA_TYPE_MAX); 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", pr_warn_ratelimited("netlink: '%s': attribute type %d has an invalid length.\n",
current->comm, type); current->comm, type);
} }
switch (pt->type) { switch (pt->type) {
case NLA_EXACT_LEN:
if (attrlen != pt->len)
return -ERANGE;
break;
case NLA_REJECT: case NLA_REJECT:
if (pt->validation_data && error_msg) if (pt->validation_data && error_msg)
*error_msg = pt->validation_data; *error_msg = pt->validation_data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment