diff options
author | Johannes Berg <johannes.berg@intel.com> | 2019-04-26 14:07:27 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-27 17:07:21 -0400 |
commit | 6f455f5f4e9c28aefaefbe18ce7304b499645d75 (patch) | |
tree | f28d52c28e15bb7bf9cb4b58ab57d6b1aae2a769 | |
parent | f6ad55a6a184ebdf3d98a90eab0895f73ce9797e (diff) | |
download | linux-6f455f5f4e9c28aefaefbe18ce7304b499645d75.tar.gz linux-6f455f5f4e9c28aefaefbe18ce7304b499645d75.tar.bz2 linux-6f455f5f4e9c28aefaefbe18ce7304b499645d75.zip |
netlink: add NLA_MIN_LEN
Rather than using NLA_UNSPEC for this type of thing, use NLA_MIN_LEN
so we can make NLA_UNSPEC be NLA_REJECT under certain conditions for
future attributes.
While at it, also use NLA_EXACT_LEN for the struct example.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/netlink.h | 6 | ||||
-rw-r--r-- | lib/nlattr.c | 9 |
2 files changed, 13 insertions, 2 deletions
diff --git a/include/net/netlink.h b/include/net/netlink.h index 1f18b47f41b4..c77ed51c18f1 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -183,6 +183,7 @@ enum { NLA_REJECT, NLA_EXACT_LEN, NLA_EXACT_LEN_WARN, + NLA_MIN_LEN, __NLA_TYPE_MAX, }; @@ -212,6 +213,7 @@ enum nla_policy_validation { * NLA_NUL_STRING Maximum length of string (excluding NUL) * NLA_FLAG Unused * NLA_BINARY Maximum length of attribute payload + * NLA_MIN_LEN Minimum length of attribute payload * NLA_NESTED, * NLA_NESTED_ARRAY Length verification is done by checking len of * nested header (or empty); len field is used if @@ -230,6 +232,7 @@ enum nla_policy_validation { * it is rejected. * NLA_EXACT_LEN_WARN Attribute should have exactly this length, a warning * is logged if it is longer, shorter is rejected. + * NLA_MIN_LEN Minimum length of attribute payload * All other Minimum length of attribute payload * * Meaning of `validation_data' field: @@ -281,7 +284,7 @@ enum nla_policy_validation { * static const struct nla_policy my_policy[ATTR_MAX+1] = { * [ATTR_FOO] = { .type = NLA_U16 }, * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, - * [ATTR_BAZ] = { .len = sizeof(struct mystruct) }, + * [ATTR_BAZ] = { .type = NLA_EXACT_LEN, .len = sizeof(struct mystruct) }, * [ATTR_GOO] = { .type = NLA_BITFIELD32, .validation_data = &myvalidflags }, * }; */ @@ -302,6 +305,7 @@ struct nla_policy { #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_MIN_LEN(_len) { .type = NLA_MIN_LEN, .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) diff --git a/lib/nlattr.c b/lib/nlattr.c index d26de6156b97..465c9e8ef8a5 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -278,10 +278,17 @@ static int validate_nla(const struct nlattr *nla, int maxtype, } } break; + + case NLA_UNSPEC: + case NLA_MIN_LEN: + if (attrlen < pt->len) + goto out_err; + break; + default: if (pt->len) minlen = pt->len; - else if (pt->type != NLA_UNSPEC) + else minlen = nla_attr_minlen[pt->type]; if (attrlen < minlen) |