Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netlink: add NLA_MIN_LEN

Rather than using NLA_UNSPEC for this type of thing, use NLA_MIN_LEN
so we can make NLA_UNSPEC be NLA_REJECT under certain conditions for
future attributes.

While at it, also use NLA_EXACT_LEN for the struct example.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Johannes Berg and committed by
David S. Miller
6f455f5f f6ad55a6

+13 -2
+5 -1
include/net/netlink.h
··· 183 183 NLA_REJECT, 184 184 NLA_EXACT_LEN, 185 185 NLA_EXACT_LEN_WARN, 186 + NLA_MIN_LEN, 186 187 __NLA_TYPE_MAX, 187 188 }; 188 189 ··· 213 212 * NLA_NUL_STRING Maximum length of string (excluding NUL) 214 213 * NLA_FLAG Unused 215 214 * NLA_BINARY Maximum length of attribute payload 215 + * NLA_MIN_LEN Minimum length of attribute payload 216 216 * NLA_NESTED, 217 217 * NLA_NESTED_ARRAY Length verification is done by checking len of 218 218 * nested header (or empty); len field is used if ··· 232 230 * it is rejected. 233 231 * NLA_EXACT_LEN_WARN Attribute should have exactly this length, a warning 234 232 * is logged if it is longer, shorter is rejected. 233 + * NLA_MIN_LEN Minimum length of attribute payload 235 234 * All other Minimum length of attribute payload 236 235 * 237 236 * Meaning of `validation_data' field: ··· 284 281 * static const struct nla_policy my_policy[ATTR_MAX+1] = { 285 282 * [ATTR_FOO] = { .type = NLA_U16 }, 286 283 * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, 287 - * [ATTR_BAZ] = { .len = sizeof(struct mystruct) }, 284 + * [ATTR_BAZ] = { .type = NLA_EXACT_LEN, .len = sizeof(struct mystruct) }, 288 285 * [ATTR_GOO] = { .type = NLA_BITFIELD32, .validation_data = &myvalidflags }, 289 286 * }; 290 287 */ ··· 305 302 #define NLA_POLICY_EXACT_LEN(_len) { .type = NLA_EXACT_LEN, .len = _len } 306 303 #define NLA_POLICY_EXACT_LEN_WARN(_len) { .type = NLA_EXACT_LEN_WARN, \ 307 304 .len = _len } 305 + #define NLA_POLICY_MIN_LEN(_len) { .type = NLA_MIN_LEN, .len = _len } 308 306 309 307 #define NLA_POLICY_ETH_ADDR NLA_POLICY_EXACT_LEN(ETH_ALEN) 310 308 #define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN)
+8 -1
lib/nlattr.c
··· 278 278 } 279 279 } 280 280 break; 281 + 282 + case NLA_UNSPEC: 283 + case NLA_MIN_LEN: 284 + if (attrlen < pt->len) 285 + goto out_err; 286 + break; 287 + 281 288 default: 282 289 if (pt->len) 283 290 minlen = pt->len; 284 - else if (pt->type != NLA_UNSPEC) 291 + else 285 292 minlen = nla_attr_minlen[pt->type]; 286 293 287 294 if (attrlen < minlen)