summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netlink.h6
-rw-r--r--lib/nlattr.c9
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)