[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20180927092836.6117-3-johannes@sipsolutions.net>
Date: Thu, 27 Sep 2018 11:28:36 +0200
From: Johannes Berg <johannes@...solutions.net>
To: linux-wireless@...r.kernel.org, netdev@...r.kernel.org
Cc: Michal Kubecek <mkubecek@...e.cz>,
Johannes Berg <johannes.berg@...el.com>
Subject: [PATCH v2 2/2] netlink: add validation function to policy
From: Johannes Berg <johannes.berg@...el.com>
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@...el.com>
---
include/net/netlink.h | 24 +++++++++++++++++++++++-
lib/nlattr.c | 7 +++++++
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/include/net/netlink.h b/include/net/netlink.h
index d34ceeba82a8..6a106ef5ca56 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -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
diff --git a/lib/nlattr.c b/lib/nlattr.c
index 5670e4b7dfef..1e900bb414ef 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -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;
--
2.14.4
Powered by blists - more mailing lists