netlink: add validation function to policy
Add the ability to have an arbitrary validation function attached to a netlink policy that doesn't already use the validation_data pointer in another way. This can be useful to validate for example the content of a binary attribute, like in nl80211 the "(information) elements", which must be valid streams of "u8 type, u8 length, u8 value[length]". Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3e48be05f3
commit
33188bd643
|
@ -193,13 +193,14 @@ enum nla_policy_validation {
|
|||
NLA_VALIDATE_RANGE,
|
||||
NLA_VALIDATE_MIN,
|
||||
NLA_VALIDATE_MAX,
|
||||
NLA_VALIDATE_FUNCTION,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nla_policy - attribute validation policy
|
||||
* @type: Type of attribute or NLA_UNSPEC
|
||||
* @validation_type: type of attribute validation done in addition to
|
||||
* type-specific validation (e.g. range), see
|
||||
* type-specific validation (e.g. range, function call), see
|
||||
* &enum nla_policy_validation
|
||||
* @len: Type specific length of payload
|
||||
*
|
||||
|
@ -269,6 +270,13 @@ enum nla_policy_validation {
|
|||
* of s16 - do that as usual in the code instead.
|
||||
* All other Unused - but note that it's a union
|
||||
*
|
||||
* Meaning of `validate' field, use via NLA_POLICY_VALIDATE_FN:
|
||||
* NLA_BINARY Validation function called for the attribute,
|
||||
* not compatible with use of the validation_data
|
||||
* as in NLA_BITFIELD32, NLA_REJECT, NLA_NESTED and
|
||||
* NLA_NESTED_ARRAY.
|
||||
* All other Unused - but note that it's a union
|
||||
*
|
||||
* Example:
|
||||
* static const struct nla_policy my_policy[ATTR_MAX+1] = {
|
||||
* [ATTR_FOO] = { .type = NLA_U16 },
|
||||
|
@ -286,6 +294,8 @@ struct nla_policy {
|
|||
struct {
|
||||
s16 min, max;
|
||||
};
|
||||
int (*validate)(const struct nlattr *attr,
|
||||
struct netlink_ext_ack *extack);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -307,6 +317,11 @@ struct nla_policy {
|
|||
tp == NLA_S16 || tp == NLA_U16 || \
|
||||
tp == NLA_S32 || tp == NLA_U32 || \
|
||||
tp == NLA_S64 || tp == NLA_U64) + tp)
|
||||
#define NLA_ENSURE_NO_VALIDATION_PTR(tp) \
|
||||
(__NLA_ENSURE(tp != NLA_BITFIELD32 && \
|
||||
tp != NLA_REJECT && \
|
||||
tp != NLA_NESTED && \
|
||||
tp != NLA_NESTED_ARRAY) + tp)
|
||||
|
||||
#define NLA_POLICY_RANGE(tp, _min, _max) { \
|
||||
.type = NLA_ENSURE_INT_TYPE(tp), \
|
||||
|
@ -327,6 +342,13 @@ struct nla_policy {
|
|||
.max = _max, \
|
||||
}
|
||||
|
||||
#define NLA_POLICY_VALIDATE_FN(tp, fn, ...) { \
|
||||
.type = NLA_ENSURE_NO_VALIDATION_PTR(tp), \
|
||||
.validation_type = NLA_VALIDATE_FUNCTION, \
|
||||
.validate = fn, \
|
||||
.len = __VA_ARGS__ + 0, \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct nl_info - netlink source information
|
||||
* @nlh: Netlink message header of original request
|
||||
|
|
|
@ -300,6 +300,13 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
|
|||
if (err)
|
||||
return err;
|
||||
break;
|
||||
case NLA_VALIDATE_FUNCTION:
|
||||
if (pt->validate) {
|
||||
err = pt->validate(nla, extack);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue