Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * NETLINK Policy advertisement to userspace
4 : *
5 : * Authors: Johannes Berg <johannes@sipsolutions.net>
6 : *
7 : * Copyright 2019 Intel Corporation
8 : */
9 :
10 : #include <linux/kernel.h>
11 : #include <linux/errno.h>
12 : #include <linux/types.h>
13 : #include <net/netlink.h>
14 :
15 : #define INITIAL_POLICIES_ALLOC 10
16 :
17 : struct netlink_policy_dump_state {
18 : unsigned int policy_idx;
19 : unsigned int attr_idx;
20 : unsigned int n_alloc;
21 : struct {
22 : const struct nla_policy *policy;
23 : unsigned int maxtype;
24 : } policies[];
25 : };
26 :
27 0 : static int add_policy(struct netlink_policy_dump_state **statep,
28 : const struct nla_policy *policy,
29 : unsigned int maxtype)
30 : {
31 0 : struct netlink_policy_dump_state *state = *statep;
32 0 : unsigned int n_alloc, i;
33 :
34 0 : if (!policy || !maxtype)
35 : return 0;
36 :
37 0 : for (i = 0; i < state->n_alloc; i++) {
38 0 : if (state->policies[i].policy == policy &&
39 0 : state->policies[i].maxtype == maxtype)
40 : return 0;
41 :
42 0 : if (!state->policies[i].policy) {
43 0 : state->policies[i].policy = policy;
44 0 : state->policies[i].maxtype = maxtype;
45 0 : return 0;
46 : }
47 : }
48 :
49 0 : n_alloc = state->n_alloc + INITIAL_POLICIES_ALLOC;
50 0 : state = krealloc(state, struct_size(state, policies, n_alloc),
51 : GFP_KERNEL);
52 0 : if (!state)
53 : return -ENOMEM;
54 :
55 0 : memset(&state->policies[state->n_alloc], 0,
56 0 : flex_array_size(state, policies, n_alloc - state->n_alloc));
57 :
58 0 : state->policies[state->n_alloc].policy = policy;
59 0 : state->policies[state->n_alloc].maxtype = maxtype;
60 0 : state->n_alloc = n_alloc;
61 0 : *statep = state;
62 :
63 0 : return 0;
64 : }
65 :
66 : /**
67 : * netlink_policy_dump_get_policy_idx - retrieve policy index
68 : * @state: the policy dump state
69 : * @policy: the policy to find
70 : * @maxtype: the policy's maxattr
71 : *
72 : * Returns: the index of the given policy in the dump state
73 : *
74 : * Call this to find a policy index when you've added multiple and e.g.
75 : * need to tell userspace which command has which policy (by index).
76 : *
77 : * Note: this will WARN and return 0 if the policy isn't found, which
78 : * means it wasn't added in the first place, which would be an
79 : * internal consistency bug.
80 : */
81 0 : int netlink_policy_dump_get_policy_idx(struct netlink_policy_dump_state *state,
82 : const struct nla_policy *policy,
83 : unsigned int maxtype)
84 : {
85 0 : unsigned int i;
86 :
87 0 : if (WARN_ON(!policy || !maxtype))
88 : return 0;
89 :
90 0 : for (i = 0; i < state->n_alloc; i++) {
91 0 : if (state->policies[i].policy == policy &&
92 0 : state->policies[i].maxtype == maxtype)
93 0 : return i;
94 : }
95 :
96 0 : WARN_ON(1);
97 0 : return 0;
98 : }
99 :
100 0 : static struct netlink_policy_dump_state *alloc_state(void)
101 : {
102 0 : struct netlink_policy_dump_state *state;
103 :
104 0 : state = kzalloc(struct_size(state, policies, INITIAL_POLICIES_ALLOC),
105 : GFP_KERNEL);
106 0 : if (!state)
107 0 : return ERR_PTR(-ENOMEM);
108 0 : state->n_alloc = INITIAL_POLICIES_ALLOC;
109 :
110 0 : return state;
111 : }
112 :
113 : /**
114 : * netlink_policy_dump_add_policy - add a policy to the dump
115 : * @pstate: state to add to, may be reallocated, must be %NULL the first time
116 : * @policy: the new policy to add to the dump
117 : * @maxtype: the new policy's max attr type
118 : *
119 : * Returns: 0 on success, a negative error code otherwise.
120 : *
121 : * Call this to allocate a policy dump state, and to add policies to it. This
122 : * should be called from the dump start() callback.
123 : *
124 : * Note: on failures, any previously allocated state is freed.
125 : */
126 0 : int netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,
127 : const struct nla_policy *policy,
128 : unsigned int maxtype)
129 : {
130 0 : struct netlink_policy_dump_state *state = *pstate;
131 0 : unsigned int policy_idx;
132 0 : int err;
133 :
134 0 : if (!state) {
135 0 : state = alloc_state();
136 0 : if (IS_ERR(state))
137 0 : return PTR_ERR(state);
138 : }
139 :
140 : /*
141 : * walk the policies and nested ones first, and build
142 : * a linear list of them.
143 : */
144 :
145 0 : err = add_policy(&state, policy, maxtype);
146 0 : if (err)
147 : return err;
148 :
149 0 : for (policy_idx = 0;
150 0 : policy_idx < state->n_alloc && state->policies[policy_idx].policy;
151 0 : policy_idx++) {
152 : const struct nla_policy *policy;
153 : unsigned int type;
154 :
155 0 : policy = state->policies[policy_idx].policy;
156 :
157 0 : for (type = 0;
158 0 : type <= state->policies[policy_idx].maxtype;
159 0 : type++) {
160 0 : switch (policy[type].type) {
161 0 : case NLA_NESTED:
162 : case NLA_NESTED_ARRAY:
163 0 : err = add_policy(&state,
164 : policy[type].nested_policy,
165 0 : policy[type].len);
166 0 : if (err)
167 0 : return err;
168 : break;
169 : default:
170 : break;
171 : }
172 : }
173 : }
174 :
175 0 : *pstate = state;
176 0 : return 0;
177 : }
178 :
179 : static bool
180 0 : netlink_policy_dump_finished(struct netlink_policy_dump_state *state)
181 : {
182 0 : return state->policy_idx >= state->n_alloc ||
183 0 : !state->policies[state->policy_idx].policy;
184 : }
185 :
186 : /**
187 : * netlink_policy_dump_loop - dumping loop indicator
188 : * @state: the policy dump state
189 : *
190 : * Returns: %true if the dump continues, %false otherwise
191 : *
192 : * Note: this frees the dump state when finishing
193 : */
194 0 : bool netlink_policy_dump_loop(struct netlink_policy_dump_state *state)
195 : {
196 0 : return !netlink_policy_dump_finished(state);
197 : }
198 :
199 0 : int netlink_policy_dump_attr_size_estimate(const struct nla_policy *pt)
200 : {
201 : /* nested + type */
202 0 : int common = 2 * nla_attr_size(sizeof(u32));
203 :
204 0 : switch (pt->type) {
205 : case NLA_UNSPEC:
206 : case NLA_REJECT:
207 : /* these actually don't need any space */
208 : return 0;
209 : case NLA_NESTED:
210 : case NLA_NESTED_ARRAY:
211 : /* common, policy idx, policy maxattr */
212 : return common + 2 * nla_attr_size(sizeof(u32));
213 : case NLA_U8:
214 : case NLA_U16:
215 : case NLA_U32:
216 : case NLA_U64:
217 : case NLA_MSECS:
218 : case NLA_S8:
219 : case NLA_S16:
220 : case NLA_S32:
221 : case NLA_S64:
222 : /* maximum is common, u64 min/max with padding */
223 : return common +
224 : 2 * (nla_attr_size(0) + nla_attr_size(sizeof(u64)));
225 : case NLA_BITFIELD32:
226 : return common + nla_attr_size(sizeof(u32));
227 : case NLA_STRING:
228 : case NLA_NUL_STRING:
229 : case NLA_BINARY:
230 : /* maximum is common, u32 min-length/max-length */
231 : return common + 2 * nla_attr_size(sizeof(u32));
232 : case NLA_FLAG:
233 : return common;
234 : }
235 :
236 : /* this should then cause a warning later */
237 : return 0;
238 : }
239 :
240 : static int
241 0 : __netlink_policy_dump_write_attr(struct netlink_policy_dump_state *state,
242 : struct sk_buff *skb,
243 : const struct nla_policy *pt,
244 : int nestattr)
245 : {
246 0 : int estimate = netlink_policy_dump_attr_size_estimate(pt);
247 0 : enum netlink_attribute_type type;
248 0 : struct nlattr *attr;
249 :
250 0 : attr = nla_nest_start(skb, nestattr);
251 0 : if (!attr)
252 : return -ENOBUFS;
253 :
254 0 : switch (pt->type) {
255 : default:
256 : case NLA_UNSPEC:
257 : case NLA_REJECT:
258 : /* skip - use NLA_MIN_LEN to advertise such */
259 0 : nla_nest_cancel(skb, attr);
260 0 : return -ENODATA;
261 : case NLA_NESTED:
262 : type = NL_ATTR_TYPE_NESTED;
263 0 : fallthrough;
264 0 : case NLA_NESTED_ARRAY:
265 0 : if (pt->type == NLA_NESTED_ARRAY)
266 0 : type = NL_ATTR_TYPE_NESTED_ARRAY;
267 0 : if (state && pt->nested_policy && pt->len &&
268 0 : (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_IDX,
269 0 : netlink_policy_dump_get_policy_idx(state,
270 : pt->nested_policy,
271 0 : pt->len)) ||
272 0 : nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE,
273 0 : pt->len)))
274 0 : goto nla_put_failure;
275 : break;
276 0 : case NLA_U8:
277 : case NLA_U16:
278 : case NLA_U32:
279 : case NLA_U64:
280 : case NLA_MSECS: {
281 0 : struct netlink_range_validation range;
282 :
283 0 : if (pt->type == NLA_U8)
284 : type = NL_ATTR_TYPE_U8;
285 0 : else if (pt->type == NLA_U16)
286 : type = NL_ATTR_TYPE_U16;
287 0 : else if (pt->type == NLA_U32)
288 : type = NL_ATTR_TYPE_U32;
289 : else
290 0 : type = NL_ATTR_TYPE_U64;
291 :
292 0 : if (pt->validation_type == NLA_VALIDATE_MASK) {
293 0 : if (nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MASK,
294 0 : pt->mask,
295 : NL_POLICY_TYPE_ATTR_PAD))
296 0 : goto nla_put_failure;
297 0 : break;
298 : }
299 :
300 0 : nla_get_range_unsigned(pt, &range);
301 :
302 0 : if (nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MIN_VALUE_U,
303 0 : range.min, NL_POLICY_TYPE_ATTR_PAD) ||
304 0 : nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MAX_VALUE_U,
305 : range.max, NL_POLICY_TYPE_ATTR_PAD))
306 0 : goto nla_put_failure;
307 : break;
308 : }
309 0 : case NLA_S8:
310 : case NLA_S16:
311 : case NLA_S32:
312 : case NLA_S64: {
313 0 : struct netlink_range_validation_signed range;
314 :
315 0 : if (pt->type == NLA_S8)
316 : type = NL_ATTR_TYPE_S8;
317 0 : else if (pt->type == NLA_S16)
318 : type = NL_ATTR_TYPE_S16;
319 0 : else if (pt->type == NLA_S32)
320 : type = NL_ATTR_TYPE_S32;
321 : else
322 0 : type = NL_ATTR_TYPE_S64;
323 :
324 0 : nla_get_range_signed(pt, &range);
325 :
326 0 : if (nla_put_s64(skb, NL_POLICY_TYPE_ATTR_MIN_VALUE_S,
327 0 : range.min, NL_POLICY_TYPE_ATTR_PAD) ||
328 0 : nla_put_s64(skb, NL_POLICY_TYPE_ATTR_MAX_VALUE_S,
329 : range.max, NL_POLICY_TYPE_ATTR_PAD))
330 0 : goto nla_put_failure;
331 0 : break;
332 : }
333 0 : case NLA_BITFIELD32:
334 0 : type = NL_ATTR_TYPE_BITFIELD32;
335 0 : if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_BITFIELD32_MASK,
336 : pt->bitfield32_valid))
337 0 : goto nla_put_failure;
338 : break;
339 0 : case NLA_STRING:
340 : case NLA_NUL_STRING:
341 : case NLA_BINARY:
342 0 : if (pt->type == NLA_STRING)
343 : type = NL_ATTR_TYPE_STRING;
344 0 : else if (pt->type == NLA_NUL_STRING)
345 : type = NL_ATTR_TYPE_NUL_STRING;
346 : else
347 0 : type = NL_ATTR_TYPE_BINARY;
348 :
349 0 : if (pt->validation_type == NLA_VALIDATE_RANGE ||
350 : pt->validation_type == NLA_VALIDATE_RANGE_WARN_TOO_LONG) {
351 0 : struct netlink_range_validation range;
352 :
353 0 : nla_get_range_unsigned(pt, &range);
354 :
355 0 : if (range.min &&
356 0 : nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MIN_LENGTH,
357 : range.min))
358 0 : goto nla_put_failure;
359 :
360 0 : if (range.max < U16_MAX &&
361 0 : nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MAX_LENGTH,
362 : range.max))
363 0 : goto nla_put_failure;
364 0 : } else if (pt->len &&
365 0 : nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MAX_LENGTH,
366 : pt->len)) {
367 0 : goto nla_put_failure;
368 : }
369 : break;
370 : case NLA_FLAG:
371 : type = NL_ATTR_TYPE_FLAG;
372 : break;
373 : }
374 :
375 0 : if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_TYPE, type))
376 0 : goto nla_put_failure;
377 :
378 0 : nla_nest_end(skb, attr);
379 0 : WARN_ON(attr->nla_len > estimate);
380 :
381 : return 0;
382 0 : nla_put_failure:
383 0 : nla_nest_cancel(skb, attr);
384 0 : return -ENOBUFS;
385 : }
386 :
387 : /**
388 : * netlink_policy_dump_write_attr - write a given attribute policy
389 : * @skb: the message skb to write to
390 : * @pt: the attribute's policy
391 : * @nestattr: the nested attribute ID to use
392 : *
393 : * Returns: 0 on success, an error code otherwise; -%ENODATA is
394 : * special, indicating that there's no policy data and
395 : * the attribute is generally rejected.
396 : */
397 0 : int netlink_policy_dump_write_attr(struct sk_buff *skb,
398 : const struct nla_policy *pt,
399 : int nestattr)
400 : {
401 0 : return __netlink_policy_dump_write_attr(NULL, skb, pt, nestattr);
402 : }
403 :
404 : /**
405 : * netlink_policy_dump_write - write current policy dump attributes
406 : * @skb: the message skb to write to
407 : * @state: the policy dump state
408 : *
409 : * Returns: 0 on success, an error code otherwise
410 : */
411 0 : int netlink_policy_dump_write(struct sk_buff *skb,
412 : struct netlink_policy_dump_state *state)
413 : {
414 0 : const struct nla_policy *pt;
415 0 : struct nlattr *policy;
416 0 : bool again;
417 0 : int err;
418 :
419 0 : send_attribute:
420 0 : again = false;
421 :
422 0 : pt = &state->policies[state->policy_idx].policy[state->attr_idx];
423 :
424 0 : policy = nla_nest_start(skb, state->policy_idx);
425 0 : if (!policy)
426 : return -ENOBUFS;
427 :
428 0 : err = __netlink_policy_dump_write_attr(state, skb, pt, state->attr_idx);
429 0 : if (err == -ENODATA) {
430 0 : nla_nest_cancel(skb, policy);
431 0 : again = true;
432 0 : goto next;
433 0 : } else if (err) {
434 0 : goto nla_put_failure;
435 : }
436 :
437 : /* finish and move state to next attribute */
438 0 : nla_nest_end(skb, policy);
439 :
440 0 : next:
441 0 : state->attr_idx += 1;
442 0 : if (state->attr_idx > state->policies[state->policy_idx].maxtype) {
443 0 : state->attr_idx = 0;
444 0 : state->policy_idx++;
445 : }
446 :
447 0 : if (again) {
448 0 : if (netlink_policy_dump_finished(state))
449 : return -ENODATA;
450 0 : goto send_attribute;
451 : }
452 :
453 : return 0;
454 :
455 0 : nla_put_failure:
456 0 : nla_nest_cancel(skb, policy);
457 0 : return -ENOBUFS;
458 : }
459 :
460 : /**
461 : * netlink_policy_dump_free - free policy dump state
462 : * @state: the policy dump state to free
463 : *
464 : * Call this from the done() method to ensure dump state is freed.
465 : */
466 0 : void netlink_policy_dump_free(struct netlink_policy_dump_state *state)
467 : {
468 0 : kfree(state);
469 0 : }
|