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>
This commit is contained in:
Johannes Berg 2019-04-26 14:07:27 +02:00 committed by David S. Miller
parent f6ad55a6a1
commit 6f455f5f4e
2 changed files with 13 additions and 2 deletions

View File

@ -183,6 +183,7 @@ enum {
NLA_REJECT, NLA_REJECT,
NLA_EXACT_LEN, NLA_EXACT_LEN,
NLA_EXACT_LEN_WARN, NLA_EXACT_LEN_WARN,
NLA_MIN_LEN,
__NLA_TYPE_MAX, __NLA_TYPE_MAX,
}; };
@ -212,6 +213,7 @@ enum nla_policy_validation {
* NLA_NUL_STRING Maximum length of string (excluding NUL) * NLA_NUL_STRING Maximum length of string (excluding NUL)
* NLA_FLAG Unused * NLA_FLAG Unused
* NLA_BINARY Maximum length of attribute payload * NLA_BINARY Maximum length of attribute payload
* NLA_MIN_LEN Minimum length of attribute payload
* NLA_NESTED, * NLA_NESTED,
* NLA_NESTED_ARRAY Length verification is done by checking len of * NLA_NESTED_ARRAY Length verification is done by checking len of
* nested header (or empty); len field is used if * nested header (or empty); len field is used if
@ -230,6 +232,7 @@ enum nla_policy_validation {
* it is rejected. * it is rejected.
* NLA_EXACT_LEN_WARN Attribute should have exactly this length, a warning * NLA_EXACT_LEN_WARN Attribute should have exactly this length, a warning
* is logged if it is longer, shorter is rejected. * is logged if it is longer, shorter is rejected.
* NLA_MIN_LEN Minimum length of attribute payload
* All other Minimum length of attribute payload * All other Minimum length of attribute payload
* *
* Meaning of `validation_data' field: * Meaning of `validation_data' field:
@ -281,7 +284,7 @@ enum nla_policy_validation {
* static const struct nla_policy my_policy[ATTR_MAX+1] = { * static const struct nla_policy my_policy[ATTR_MAX+1] = {
* [ATTR_FOO] = { .type = NLA_U16 }, * [ATTR_FOO] = { .type = NLA_U16 },
* [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, * [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 }, * [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(_len) { .type = NLA_EXACT_LEN, .len = _len }
#define NLA_POLICY_EXACT_LEN_WARN(_len) { .type = NLA_EXACT_LEN_WARN, \ #define NLA_POLICY_EXACT_LEN_WARN(_len) { .type = NLA_EXACT_LEN_WARN, \
.len = _len } .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 NLA_POLICY_EXACT_LEN(ETH_ALEN)
#define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN) #define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN)

View File

@ -278,10 +278,17 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
} }
} }
break; break;
case NLA_UNSPEC:
case NLA_MIN_LEN:
if (attrlen < pt->len)
goto out_err;
break;
default: default:
if (pt->len) if (pt->len)
minlen = pt->len; minlen = pt->len;
else if (pt->type != NLA_UNSPEC) else
minlen = nla_attr_minlen[pt->type]; minlen = nla_attr_minlen[pt->type];
if (attrlen < minlen) if (attrlen < minlen)