Commit 9a659a35 authored by Johannes Berg's avatar Johannes Berg Committed by David S. Miller
Browse files

netlink: allow NLA_NESTED to specify nested policy to validate



Now that we have a validation_data pointer, and the len field in
the policy is unused for NLA_NESTED, we can allow using them both
to have nested validation. This can be nice in code, although we
still have to use nla_parse_nested() or similar which would also
take a policy; however, it also serves as documentation in the
policy without requiring a look at the code.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c29f1845
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -200,8 +200,10 @@ enum {
 *    NLA_NUL_STRING       Maximum length of string (excluding NUL)
 *    NLA_FLAG             Unused
 *    NLA_BINARY           Maximum length of attribute payload
 *    NLA_NESTED           Don't use `len' field -- length verification is
 *                         done by checking len of nested header (or empty)
 *    NLA_NESTED           Length verification is done by checking len of
 *                         nested header (or empty); len field is used if
 *                         validation_data is also used, for the max attr
 *                         number in the nested policy.
 *    NLA_U8, NLA_U16,
 *    NLA_U32, NLA_U64,
 *    NLA_S8, NLA_S16,
@@ -224,6 +226,10 @@ enum {
 *    NLA_REJECT           This attribute is always rejected and validation data
 *                         may point to a string to report as the error instead
 *                         of the generic one in extended ACK.
 *    NLA_NESTED           Points to a nested policy to validate, must also set
 *                         `len' to the max attribute number.
 *                         Note that nla_parse() will validate, but of course not
 *                         parse, the nested sub-policies.
 *    All other            Unused
 *
 * Example:
@@ -247,6 +253,9 @@ struct nla_policy {
#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_NESTED(maxattr, policy) \
	{ .type = NLA_NESTED, .validation_data = policy, .len = maxattr }

/**
 * struct nl_info - netlink source information
 * @nlh: Netlink message header of original request
+14 −0
Original line number Diff line number Diff line
@@ -155,6 +155,20 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
		 */
		if (attrlen == 0)
			break;
		if (attrlen < NLA_HDRLEN)
			goto out_err;
		if (pt->validation_data) {
			err = nla_validate(nla_data(nla), nla_len(nla), pt->len,
					   pt->validation_data, extack);
			if (err < 0) {
				/*
				 * return directly to preserve the inner
				 * error message/attribute pointer
				 */
				return err;
			}
		}
		break;
	default:
		if (pt->len)
			minlen = pt->len;