0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/errno.h>
0012 #include <linux/types.h>
0013 #include <net/netlink.h>
0014
0015 #define INITIAL_POLICIES_ALLOC 10
0016
0017 struct netlink_policy_dump_state {
0018 unsigned int policy_idx;
0019 unsigned int attr_idx;
0020 unsigned int n_alloc;
0021 struct {
0022 const struct nla_policy *policy;
0023 unsigned int maxtype;
0024 } policies[];
0025 };
0026
0027 static int add_policy(struct netlink_policy_dump_state **statep,
0028 const struct nla_policy *policy,
0029 unsigned int maxtype)
0030 {
0031 struct netlink_policy_dump_state *state = *statep;
0032 unsigned int n_alloc, i;
0033
0034 if (!policy || !maxtype)
0035 return 0;
0036
0037 for (i = 0; i < state->n_alloc; i++) {
0038 if (state->policies[i].policy == policy &&
0039 state->policies[i].maxtype == maxtype)
0040 return 0;
0041
0042 if (!state->policies[i].policy) {
0043 state->policies[i].policy = policy;
0044 state->policies[i].maxtype = maxtype;
0045 return 0;
0046 }
0047 }
0048
0049 n_alloc = state->n_alloc + INITIAL_POLICIES_ALLOC;
0050 state = krealloc(state, struct_size(state, policies, n_alloc),
0051 GFP_KERNEL);
0052 if (!state)
0053 return -ENOMEM;
0054
0055 memset(&state->policies[state->n_alloc], 0,
0056 flex_array_size(state, policies, n_alloc - state->n_alloc));
0057
0058 state->policies[state->n_alloc].policy = policy;
0059 state->policies[state->n_alloc].maxtype = maxtype;
0060 state->n_alloc = n_alloc;
0061 *statep = state;
0062
0063 return 0;
0064 }
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 int netlink_policy_dump_get_policy_idx(struct netlink_policy_dump_state *state,
0082 const struct nla_policy *policy,
0083 unsigned int maxtype)
0084 {
0085 unsigned int i;
0086
0087 if (WARN_ON(!policy || !maxtype))
0088 return 0;
0089
0090 for (i = 0; i < state->n_alloc; i++) {
0091 if (state->policies[i].policy == policy &&
0092 state->policies[i].maxtype == maxtype)
0093 return i;
0094 }
0095
0096 WARN_ON(1);
0097 return 0;
0098 }
0099
0100 static struct netlink_policy_dump_state *alloc_state(void)
0101 {
0102 struct netlink_policy_dump_state *state;
0103
0104 state = kzalloc(struct_size(state, policies, INITIAL_POLICIES_ALLOC),
0105 GFP_KERNEL);
0106 if (!state)
0107 return ERR_PTR(-ENOMEM);
0108 state->n_alloc = INITIAL_POLICIES_ALLOC;
0109
0110 return state;
0111 }
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 int netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,
0127 const struct nla_policy *policy,
0128 unsigned int maxtype)
0129 {
0130 struct netlink_policy_dump_state *state = *pstate;
0131 unsigned int policy_idx;
0132 int err;
0133
0134 if (!state) {
0135 state = alloc_state();
0136 if (IS_ERR(state))
0137 return PTR_ERR(state);
0138 }
0139
0140
0141
0142
0143
0144
0145 err = add_policy(&state, policy, maxtype);
0146 if (err)
0147 goto err_try_undo;
0148
0149 for (policy_idx = 0;
0150 policy_idx < state->n_alloc && state->policies[policy_idx].policy;
0151 policy_idx++) {
0152 const struct nla_policy *policy;
0153 unsigned int type;
0154
0155 policy = state->policies[policy_idx].policy;
0156
0157 for (type = 0;
0158 type <= state->policies[policy_idx].maxtype;
0159 type++) {
0160 switch (policy[type].type) {
0161 case NLA_NESTED:
0162 case NLA_NESTED_ARRAY:
0163 err = add_policy(&state,
0164 policy[type].nested_policy,
0165 policy[type].len);
0166 if (err)
0167 goto err_try_undo;
0168 break;
0169 default:
0170 break;
0171 }
0172 }
0173 }
0174
0175 *pstate = state;
0176 return 0;
0177
0178 err_try_undo:
0179
0180
0181
0182 if (!*pstate)
0183 netlink_policy_dump_free(state);
0184 else
0185 *pstate = state;
0186 return err;
0187 }
0188
0189 static bool
0190 netlink_policy_dump_finished(struct netlink_policy_dump_state *state)
0191 {
0192 return state->policy_idx >= state->n_alloc ||
0193 !state->policies[state->policy_idx].policy;
0194 }
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204 bool netlink_policy_dump_loop(struct netlink_policy_dump_state *state)
0205 {
0206 return !netlink_policy_dump_finished(state);
0207 }
0208
0209 int netlink_policy_dump_attr_size_estimate(const struct nla_policy *pt)
0210 {
0211
0212 int common = 2 * nla_attr_size(sizeof(u32));
0213
0214 switch (pt->type) {
0215 case NLA_UNSPEC:
0216 case NLA_REJECT:
0217
0218 return 0;
0219 case NLA_NESTED:
0220 case NLA_NESTED_ARRAY:
0221
0222 return common + 2 * nla_attr_size(sizeof(u32));
0223 case NLA_U8:
0224 case NLA_U16:
0225 case NLA_U32:
0226 case NLA_U64:
0227 case NLA_MSECS:
0228 case NLA_S8:
0229 case NLA_S16:
0230 case NLA_S32:
0231 case NLA_S64:
0232
0233 return common +
0234 2 * (nla_attr_size(0) + nla_attr_size(sizeof(u64)));
0235 case NLA_BITFIELD32:
0236 return common + nla_attr_size(sizeof(u32));
0237 case NLA_STRING:
0238 case NLA_NUL_STRING:
0239 case NLA_BINARY:
0240
0241 return common + 2 * nla_attr_size(sizeof(u32));
0242 case NLA_FLAG:
0243 return common;
0244 }
0245
0246
0247 return 0;
0248 }
0249
0250 static int
0251 __netlink_policy_dump_write_attr(struct netlink_policy_dump_state *state,
0252 struct sk_buff *skb,
0253 const struct nla_policy *pt,
0254 int nestattr)
0255 {
0256 int estimate = netlink_policy_dump_attr_size_estimate(pt);
0257 enum netlink_attribute_type type;
0258 struct nlattr *attr;
0259
0260 attr = nla_nest_start(skb, nestattr);
0261 if (!attr)
0262 return -ENOBUFS;
0263
0264 switch (pt->type) {
0265 default:
0266 case NLA_UNSPEC:
0267 case NLA_REJECT:
0268
0269 nla_nest_cancel(skb, attr);
0270 return -ENODATA;
0271 case NLA_NESTED:
0272 type = NL_ATTR_TYPE_NESTED;
0273 fallthrough;
0274 case NLA_NESTED_ARRAY:
0275 if (pt->type == NLA_NESTED_ARRAY)
0276 type = NL_ATTR_TYPE_NESTED_ARRAY;
0277 if (state && pt->nested_policy && pt->len &&
0278 (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_IDX,
0279 netlink_policy_dump_get_policy_idx(state,
0280 pt->nested_policy,
0281 pt->len)) ||
0282 nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE,
0283 pt->len)))
0284 goto nla_put_failure;
0285 break;
0286 case NLA_U8:
0287 case NLA_U16:
0288 case NLA_U32:
0289 case NLA_U64:
0290 case NLA_MSECS: {
0291 struct netlink_range_validation range;
0292
0293 if (pt->type == NLA_U8)
0294 type = NL_ATTR_TYPE_U8;
0295 else if (pt->type == NLA_U16)
0296 type = NL_ATTR_TYPE_U16;
0297 else if (pt->type == NLA_U32)
0298 type = NL_ATTR_TYPE_U32;
0299 else
0300 type = NL_ATTR_TYPE_U64;
0301
0302 if (pt->validation_type == NLA_VALIDATE_MASK) {
0303 if (nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MASK,
0304 pt->mask,
0305 NL_POLICY_TYPE_ATTR_PAD))
0306 goto nla_put_failure;
0307 break;
0308 }
0309
0310 nla_get_range_unsigned(pt, &range);
0311
0312 if (nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MIN_VALUE_U,
0313 range.min, NL_POLICY_TYPE_ATTR_PAD) ||
0314 nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MAX_VALUE_U,
0315 range.max, NL_POLICY_TYPE_ATTR_PAD))
0316 goto nla_put_failure;
0317 break;
0318 }
0319 case NLA_S8:
0320 case NLA_S16:
0321 case NLA_S32:
0322 case NLA_S64: {
0323 struct netlink_range_validation_signed range;
0324
0325 if (pt->type == NLA_S8)
0326 type = NL_ATTR_TYPE_S8;
0327 else if (pt->type == NLA_S16)
0328 type = NL_ATTR_TYPE_S16;
0329 else if (pt->type == NLA_S32)
0330 type = NL_ATTR_TYPE_S32;
0331 else
0332 type = NL_ATTR_TYPE_S64;
0333
0334 nla_get_range_signed(pt, &range);
0335
0336 if (nla_put_s64(skb, NL_POLICY_TYPE_ATTR_MIN_VALUE_S,
0337 range.min, NL_POLICY_TYPE_ATTR_PAD) ||
0338 nla_put_s64(skb, NL_POLICY_TYPE_ATTR_MAX_VALUE_S,
0339 range.max, NL_POLICY_TYPE_ATTR_PAD))
0340 goto nla_put_failure;
0341 break;
0342 }
0343 case NLA_BITFIELD32:
0344 type = NL_ATTR_TYPE_BITFIELD32;
0345 if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_BITFIELD32_MASK,
0346 pt->bitfield32_valid))
0347 goto nla_put_failure;
0348 break;
0349 case NLA_STRING:
0350 case NLA_NUL_STRING:
0351 case NLA_BINARY:
0352 if (pt->type == NLA_STRING)
0353 type = NL_ATTR_TYPE_STRING;
0354 else if (pt->type == NLA_NUL_STRING)
0355 type = NL_ATTR_TYPE_NUL_STRING;
0356 else
0357 type = NL_ATTR_TYPE_BINARY;
0358
0359 if (pt->validation_type == NLA_VALIDATE_RANGE ||
0360 pt->validation_type == NLA_VALIDATE_RANGE_WARN_TOO_LONG) {
0361 struct netlink_range_validation range;
0362
0363 nla_get_range_unsigned(pt, &range);
0364
0365 if (range.min &&
0366 nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MIN_LENGTH,
0367 range.min))
0368 goto nla_put_failure;
0369
0370 if (range.max < U16_MAX &&
0371 nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MAX_LENGTH,
0372 range.max))
0373 goto nla_put_failure;
0374 } else if (pt->len &&
0375 nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MAX_LENGTH,
0376 pt->len)) {
0377 goto nla_put_failure;
0378 }
0379 break;
0380 case NLA_FLAG:
0381 type = NL_ATTR_TYPE_FLAG;
0382 break;
0383 }
0384
0385 if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_TYPE, type))
0386 goto nla_put_failure;
0387
0388 nla_nest_end(skb, attr);
0389 WARN_ON(attr->nla_len > estimate);
0390
0391 return 0;
0392 nla_put_failure:
0393 nla_nest_cancel(skb, attr);
0394 return -ENOBUFS;
0395 }
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407 int netlink_policy_dump_write_attr(struct sk_buff *skb,
0408 const struct nla_policy *pt,
0409 int nestattr)
0410 {
0411 return __netlink_policy_dump_write_attr(NULL, skb, pt, nestattr);
0412 }
0413
0414
0415
0416
0417
0418
0419
0420
0421 int netlink_policy_dump_write(struct sk_buff *skb,
0422 struct netlink_policy_dump_state *state)
0423 {
0424 const struct nla_policy *pt;
0425 struct nlattr *policy;
0426 bool again;
0427 int err;
0428
0429 send_attribute:
0430 again = false;
0431
0432 pt = &state->policies[state->policy_idx].policy[state->attr_idx];
0433
0434 policy = nla_nest_start(skb, state->policy_idx);
0435 if (!policy)
0436 return -ENOBUFS;
0437
0438 err = __netlink_policy_dump_write_attr(state, skb, pt, state->attr_idx);
0439 if (err == -ENODATA) {
0440 nla_nest_cancel(skb, policy);
0441 again = true;
0442 goto next;
0443 } else if (err) {
0444 goto nla_put_failure;
0445 }
0446
0447
0448 nla_nest_end(skb, policy);
0449
0450 next:
0451 state->attr_idx += 1;
0452 if (state->attr_idx > state->policies[state->policy_idx].maxtype) {
0453 state->attr_idx = 0;
0454 state->policy_idx++;
0455 }
0456
0457 if (again) {
0458 if (netlink_policy_dump_finished(state))
0459 return -ENODATA;
0460 goto send_attribute;
0461 }
0462
0463 return 0;
0464
0465 nla_put_failure:
0466 nla_nest_cancel(skb, policy);
0467 return -ENOBUFS;
0468 }
0469
0470
0471
0472
0473
0474
0475
0476 void netlink_policy_dump_free(struct netlink_policy_dump_state *state)
0477 {
0478 kfree(state);
0479 }