diff options
-rw-r--r-- | include/net/netlink.h | 6 | ||||
-rw-r--r-- | lib/nlattr.c | 9 |
2 files changed, 13 insertions, 2 deletions
diff --git a/include/net/netlink.h b/include/net/netlink.h index 1f18b47f41b4..c77ed51c18f1 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h | |||
@@ -183,6 +183,7 @@ enum { | |||
183 | NLA_REJECT, | 183 | NLA_REJECT, |
184 | NLA_EXACT_LEN, | 184 | NLA_EXACT_LEN, |
185 | NLA_EXACT_LEN_WARN, | 185 | NLA_EXACT_LEN_WARN, |
186 | NLA_MIN_LEN, | ||
186 | __NLA_TYPE_MAX, | 187 | __NLA_TYPE_MAX, |
187 | }; | 188 | }; |
188 | 189 | ||
@@ -212,6 +213,7 @@ enum nla_policy_validation { | |||
212 | * NLA_NUL_STRING Maximum length of string (excluding NUL) | 213 | * NLA_NUL_STRING Maximum length of string (excluding NUL) |
213 | * NLA_FLAG Unused | 214 | * NLA_FLAG Unused |
214 | * NLA_BINARY Maximum length of attribute payload | 215 | * NLA_BINARY Maximum length of attribute payload |
216 | * NLA_MIN_LEN Minimum length of attribute payload | ||
215 | * NLA_NESTED, | 217 | * NLA_NESTED, |
216 | * NLA_NESTED_ARRAY Length verification is done by checking len of | 218 | * NLA_NESTED_ARRAY Length verification is done by checking len of |
217 | * nested header (or empty); len field is used if | 219 | * nested header (or empty); len field is used if |
@@ -230,6 +232,7 @@ enum nla_policy_validation { | |||
230 | * it is rejected. | 232 | * it is rejected. |
231 | * NLA_EXACT_LEN_WARN Attribute should have exactly this length, a warning | 233 | * NLA_EXACT_LEN_WARN Attribute should have exactly this length, a warning |
232 | * is logged if it is longer, shorter is rejected. | 234 | * is logged if it is longer, shorter is rejected. |
235 | * NLA_MIN_LEN Minimum length of attribute payload | ||
233 | * All other Minimum length of attribute payload | 236 | * All other Minimum length of attribute payload |
234 | * | 237 | * |
235 | * Meaning of `validation_data' field: | 238 | * Meaning of `validation_data' field: |
@@ -281,7 +284,7 @@ enum nla_policy_validation { | |||
281 | * static const struct nla_policy my_policy[ATTR_MAX+1] = { | 284 | * static const struct nla_policy my_policy[ATTR_MAX+1] = { |
282 | * [ATTR_FOO] = { .type = NLA_U16 }, | 285 | * [ATTR_FOO] = { .type = NLA_U16 }, |
283 | * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, | 286 | * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ }, |
284 | * [ATTR_BAZ] = { .len = sizeof(struct mystruct) }, | 287 | * [ATTR_BAZ] = { .type = NLA_EXACT_LEN, .len = sizeof(struct mystruct) }, |
285 | * [ATTR_GOO] = { .type = NLA_BITFIELD32, .validation_data = &myvalidflags }, | 288 | * [ATTR_GOO] = { .type = NLA_BITFIELD32, .validation_data = &myvalidflags }, |
286 | * }; | 289 | * }; |
287 | */ | 290 | */ |
@@ -302,6 +305,7 @@ struct nla_policy { | |||
302 | #define NLA_POLICY_EXACT_LEN(_len) { .type = NLA_EXACT_LEN, .len = _len } | 305 | #define NLA_POLICY_EXACT_LEN(_len) { .type = NLA_EXACT_LEN, .len = _len } |
303 | #define NLA_POLICY_EXACT_LEN_WARN(_len) { .type = NLA_EXACT_LEN_WARN, \ | 306 | #define NLA_POLICY_EXACT_LEN_WARN(_len) { .type = NLA_EXACT_LEN_WARN, \ |
304 | .len = _len } | 307 | .len = _len } |
308 | #define NLA_POLICY_MIN_LEN(_len) { .type = NLA_MIN_LEN, .len = _len } | ||
305 | 309 | ||
306 | #define NLA_POLICY_ETH_ADDR NLA_POLICY_EXACT_LEN(ETH_ALEN) | 310 | #define NLA_POLICY_ETH_ADDR NLA_POLICY_EXACT_LEN(ETH_ALEN) |
307 | #define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN) | 311 | #define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN) |
diff --git a/lib/nlattr.c b/lib/nlattr.c index d26de6156b97..465c9e8ef8a5 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c | |||
@@ -278,10 +278,17 @@ static int validate_nla(const struct nlattr *nla, int maxtype, | |||
278 | } | 278 | } |
279 | } | 279 | } |
280 | break; | 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 | default: | 288 | default: |
282 | if (pt->len) | 289 | if (pt->len) |
283 | minlen = pt->len; | 290 | minlen = pt->len; |
284 | else if (pt->type != NLA_UNSPEC) | 291 | else |
285 | minlen = nla_attr_minlen[pt->type]; | 292 | minlen = nla_attr_minlen[pt->type]; |
286 | 293 | ||
287 | if (attrlen < minlen) | 294 | if (attrlen < minlen) |