summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2018-09-27 05:28:36 -0400
committerDavid S. Miller <davem@davemloft.net>2018-10-02 02:05:31 -0400
commit33188bd6430ef06d206ae4fda2cc92f14f16fd20 (patch)
treebd3980a02a9896a5a1d60936b451ce40efc44349
parent3e48be05f3c7eb6f6126939e9d957903c5cfeee5 (diff)
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>
-rw-r--r--include/net/netlink.h24
-rw-r--r--lib/nlattr.c7
2 files changed, 30 insertions, 1 deletions
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 {
193 NLA_VALIDATE_RANGE, 193 NLA_VALIDATE_RANGE,
194 NLA_VALIDATE_MIN, 194 NLA_VALIDATE_MIN,
195 NLA_VALIDATE_MAX, 195 NLA_VALIDATE_MAX,
196 NLA_VALIDATE_FUNCTION,
196}; 197};
197 198
198/** 199/**
199 * struct nla_policy - attribute validation policy 200 * struct nla_policy - attribute validation policy
200 * @type: Type of attribute or NLA_UNSPEC 201 * @type: Type of attribute or NLA_UNSPEC
201 * @validation_type: type of attribute validation done in addition to 202 * @validation_type: type of attribute validation done in addition to
202 * type-specific validation (e.g. range), see 203 * type-specific validation (e.g. range, function call), see
203 * &enum nla_policy_validation 204 * &enum nla_policy_validation
204 * @len: Type specific length of payload 205 * @len: Type specific length of payload
205 * 206 *
@@ -269,6 +270,13 @@ enum nla_policy_validation {
269 * of s16 - do that as usual in the code instead. 270 * of s16 - do that as usual in the code instead.
270 * All other Unused - but note that it's a union 271 * All other Unused - but note that it's a union
271 * 272 *
273 * Meaning of `validate' field, use via NLA_POLICY_VALIDATE_FN:
274 * NLA_BINARY Validation function called for the attribute,
275 * not compatible with use of the validation_data
276 * as in NLA_BITFIELD32, NLA_REJECT, NLA_NESTED and
277 * NLA_NESTED_ARRAY.
278 * All other Unused - but note that it's a union
279 *
272 * Example: 280 * Example:
273 * static const struct nla_policy my_policy[ATTR_MAX+1] = { 281 * static const struct nla_policy my_policy[ATTR_MAX+1] = {
274 * [ATTR_FOO] = { .type = NLA_U16 }, 282 * [ATTR_FOO] = { .type = NLA_U16 },
@@ -286,6 +294,8 @@ struct nla_policy {
286 struct { 294 struct {
287 s16 min, max; 295 s16 min, max;
288 }; 296 };
297 int (*validate)(const struct nlattr *attr,
298 struct netlink_ext_ack *extack);
289 }; 299 };
290}; 300};
291 301
@@ -307,6 +317,11 @@ struct nla_policy {
307 tp == NLA_S16 || tp == NLA_U16 || \ 317 tp == NLA_S16 || tp == NLA_U16 || \
308 tp == NLA_S32 || tp == NLA_U32 || \ 318 tp == NLA_S32 || tp == NLA_U32 || \
309 tp == NLA_S64 || tp == NLA_U64) + tp) 319 tp == NLA_S64 || tp == NLA_U64) + tp)
320#define NLA_ENSURE_NO_VALIDATION_PTR(tp) \
321 (__NLA_ENSURE(tp != NLA_BITFIELD32 && \
322 tp != NLA_REJECT && \
323 tp != NLA_NESTED && \
324 tp != NLA_NESTED_ARRAY) + tp)
310 325
311#define NLA_POLICY_RANGE(tp, _min, _max) { \ 326#define NLA_POLICY_RANGE(tp, _min, _max) { \
312 .type = NLA_ENSURE_INT_TYPE(tp), \ 327 .type = NLA_ENSURE_INT_TYPE(tp), \
@@ -327,6 +342,13 @@ struct nla_policy {
327 .max = _max, \ 342 .max = _max, \
328} 343}
329 344
345#define NLA_POLICY_VALIDATE_FN(tp, fn, ...) { \
346 .type = NLA_ENSURE_NO_VALIDATION_PTR(tp), \
347 .validation_type = NLA_VALIDATE_FUNCTION, \
348 .validate = fn, \
349 .len = __VA_ARGS__ + 0, \
350}
351
330/** 352/**
331 * struct nl_info - netlink source information 353 * struct nl_info - netlink source information
332 * @nlh: Netlink message header of original request 354 * @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,
300 if (err) 300 if (err)
301 return err; 301 return err;
302 break; 302 break;
303 case NLA_VALIDATE_FUNCTION:
304 if (pt->validate) {
305 err = pt->validate(nla, extack);
306 if (err)
307 return err;
308 }
309 break;
303 } 310 }
304 311
305 return 0; 312 return 0;