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 static int add_policy(struct netlink_policy_dump_state **statep, 28 const struct nla_policy *policy, 29 unsigned int maxtype) 30 { 31 struct netlink_policy_dump_state *state = *statep; 32 unsigned int n_alloc, i; 33 34 if (!policy || !maxtype) 35 return 0; 36 37 for (i = 0; i < state->n_alloc; i++) { 38 if (state->policies[i].policy == policy && 39 state->policies[i].maxtype == maxtype) 40 return 0; 41 42 if (!state->policies[i].policy) { 43 state->policies[i].policy = policy; 44 state->policies[i].maxtype = maxtype; 45 return 0; 46 } 47 } 48 49 n_alloc = state->n_alloc + INITIAL_POLICIES_ALLOC; 50 state = krealloc(state, struct_size(state, policies, n_alloc), 51 GFP_KERNEL); 52 if (!state) 53 return -ENOMEM; 54 55 memset(&state->policies[state->n_alloc], 0, 56 flex_array_size(state, policies, n_alloc - state->n_alloc)); 57 58 state->policies[state->n_alloc].policy = policy; 59 state->policies[state->n_alloc].maxtype = maxtype; 60 state->n_alloc = n_alloc; 61 *statep = state; 62 63 return 0; 64 } 65 66 static unsigned int get_policy_idx(struct netlink_policy_dump_state *state, 67 const struct nla_policy *policy, 68 unsigned int maxtype) 69 { 70 unsigned int i; 71 72 for (i = 0; i < state->n_alloc; i++) { 73 if (state->policies[i].policy == policy && 74 state->policies[i].maxtype == maxtype) 75 return i; 76 } 77 78 WARN_ON_ONCE(1); 79 return -1; 80 } 81 82 int netlink_policy_dump_start(const struct nla_policy *policy, 83 unsigned int maxtype, 84 struct netlink_policy_dump_state **statep) 85 { 86 struct netlink_policy_dump_state *state; 87 unsigned int policy_idx; 88 int err; 89 90 if (*statep) 91 return 0; 92 93 /* 94 * walk the policies and nested ones first, and build 95 * a linear list of them. 96 */ 97 98 state = kzalloc(struct_size(state, policies, INITIAL_POLICIES_ALLOC), 99 GFP_KERNEL); 100 if (!state) 101 return -ENOMEM; 102 state->n_alloc = INITIAL_POLICIES_ALLOC; 103 104 err = add_policy(&state, policy, maxtype); 105 if (err) 106 return err; 107 108 for (policy_idx = 0; 109 policy_idx < state->n_alloc && state->policies[policy_idx].policy; 110 policy_idx++) { 111 const struct nla_policy *policy; 112 unsigned int type; 113 114 policy = state->policies[policy_idx].policy; 115 116 for (type = 0; 117 type <= state->policies[policy_idx].maxtype; 118 type++) { 119 switch (policy[type].type) { 120 case NLA_NESTED: 121 case NLA_NESTED_ARRAY: 122 err = add_policy(&state, 123 policy[type].nested_policy, 124 policy[type].len); 125 if (err) 126 return err; 127 break; 128 default: 129 break; 130 } 131 } 132 } 133 134 *statep = state; 135 136 return 0; 137 } 138 139 static bool 140 netlink_policy_dump_finished(struct netlink_policy_dump_state *state) 141 { 142 return state->policy_idx >= state->n_alloc || 143 !state->policies[state->policy_idx].policy; 144 } 145 146 bool netlink_policy_dump_loop(struct netlink_policy_dump_state *state) 147 { 148 return !netlink_policy_dump_finished(state); 149 } 150 151 int netlink_policy_dump_write(struct sk_buff *skb, 152 struct netlink_policy_dump_state *state) 153 { 154 const struct nla_policy *pt; 155 struct nlattr *policy, *attr; 156 enum netlink_attribute_type type; 157 bool again; 158 159 send_attribute: 160 again = false; 161 162 pt = &state->policies[state->policy_idx].policy[state->attr_idx]; 163 164 policy = nla_nest_start(skb, state->policy_idx); 165 if (!policy) 166 return -ENOBUFS; 167 168 attr = nla_nest_start(skb, state->attr_idx); 169 if (!attr) 170 goto nla_put_failure; 171 172 switch (pt->type) { 173 default: 174 case NLA_UNSPEC: 175 case NLA_REJECT: 176 /* skip - use NLA_MIN_LEN to advertise such */ 177 nla_nest_cancel(skb, policy); 178 again = true; 179 goto next; 180 case NLA_NESTED: 181 type = NL_ATTR_TYPE_NESTED; 182 fallthrough; 183 case NLA_NESTED_ARRAY: 184 if (pt->type == NLA_NESTED_ARRAY) 185 type = NL_ATTR_TYPE_NESTED_ARRAY; 186 if (pt->nested_policy && pt->len && 187 (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_IDX, 188 get_policy_idx(state, pt->nested_policy, 189 pt->len)) || 190 nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE, 191 pt->len))) 192 goto nla_put_failure; 193 break; 194 case NLA_U8: 195 case NLA_U16: 196 case NLA_U32: 197 case NLA_U64: 198 case NLA_MSECS: { 199 struct netlink_range_validation range; 200 201 if (pt->type == NLA_U8) 202 type = NL_ATTR_TYPE_U8; 203 else if (pt->type == NLA_U16) 204 type = NL_ATTR_TYPE_U16; 205 else if (pt->type == NLA_U32) 206 type = NL_ATTR_TYPE_U32; 207 else 208 type = NL_ATTR_TYPE_U64; 209 210 nla_get_range_unsigned(pt, &range); 211 212 if (nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MIN_VALUE_U, 213 range.min, NL_POLICY_TYPE_ATTR_PAD) || 214 nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MAX_VALUE_U, 215 range.max, NL_POLICY_TYPE_ATTR_PAD)) 216 goto nla_put_failure; 217 break; 218 } 219 case NLA_S8: 220 case NLA_S16: 221 case NLA_S32: 222 case NLA_S64: { 223 struct netlink_range_validation_signed range; 224 225 if (pt->type == NLA_S8) 226 type = NL_ATTR_TYPE_S8; 227 else if (pt->type == NLA_S16) 228 type = NL_ATTR_TYPE_S16; 229 else if (pt->type == NLA_S32) 230 type = NL_ATTR_TYPE_S32; 231 else 232 type = NL_ATTR_TYPE_S64; 233 234 nla_get_range_signed(pt, &range); 235 236 if (nla_put_s64(skb, NL_POLICY_TYPE_ATTR_MIN_VALUE_S, 237 range.min, NL_POLICY_TYPE_ATTR_PAD) || 238 nla_put_s64(skb, NL_POLICY_TYPE_ATTR_MAX_VALUE_S, 239 range.max, NL_POLICY_TYPE_ATTR_PAD)) 240 goto nla_put_failure; 241 break; 242 } 243 case NLA_BITFIELD32: 244 type = NL_ATTR_TYPE_BITFIELD32; 245 if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_BITFIELD32_MASK, 246 pt->bitfield32_valid)) 247 goto nla_put_failure; 248 break; 249 case NLA_STRING: 250 case NLA_NUL_STRING: 251 case NLA_BINARY: 252 if (pt->type == NLA_STRING) 253 type = NL_ATTR_TYPE_STRING; 254 else if (pt->type == NLA_NUL_STRING) 255 type = NL_ATTR_TYPE_NUL_STRING; 256 else 257 type = NL_ATTR_TYPE_BINARY; 258 259 if (pt->validation_type == NLA_VALIDATE_RANGE || 260 pt->validation_type == NLA_VALIDATE_RANGE_WARN_TOO_LONG) { 261 struct netlink_range_validation range; 262 263 nla_get_range_unsigned(pt, &range); 264 265 if (range.min && 266 nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MIN_LENGTH, 267 range.min)) 268 goto nla_put_failure; 269 270 if (range.max < U16_MAX && 271 nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MAX_LENGTH, 272 range.max)) 273 goto nla_put_failure; 274 } else if (pt->len && 275 nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MAX_LENGTH, 276 pt->len)) { 277 goto nla_put_failure; 278 } 279 break; 280 case NLA_FLAG: 281 type = NL_ATTR_TYPE_FLAG; 282 break; 283 } 284 285 if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_TYPE, type)) 286 goto nla_put_failure; 287 288 /* finish and move state to next attribute */ 289 nla_nest_end(skb, attr); 290 nla_nest_end(skb, policy); 291 292 next: 293 state->attr_idx += 1; 294 if (state->attr_idx > state->policies[state->policy_idx].maxtype) { 295 state->attr_idx = 0; 296 state->policy_idx++; 297 } 298 299 if (again) { 300 if (netlink_policy_dump_finished(state)) 301 return -ENODATA; 302 goto send_attribute; 303 } 304 305 return 0; 306 307 nla_put_failure: 308 nla_nest_cancel(skb, policy); 309 return -ENOBUFS; 310 } 311 312 void netlink_policy_dump_free(struct netlink_policy_dump_state *state) 313 { 314 kfree(state); 315 } 316