diff options
author | Patrick McHardy <kaber@trash.net> | 2008-01-23 23:35:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:11:22 -0500 |
commit | 27a3421e4821734bc19496faa77b380605dc3b23 (patch) | |
tree | f9ded49845a39f41352ed09130bf3d2bd05e4ffe /net/sched | |
parent | 5feb5e1aaa887f6427b8290bce48bfb6b7010fc6 (diff) |
[NET_SCHED]: Use nla_policy for attribute validation in packet schedulers
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/sch_atm.c | 12 | ||||
-rw-r--r-- | net/sched/sch_cbq.c | 47 | ||||
-rw-r--r-- | net/sched/sch_dsmark.c | 33 | ||||
-rw-r--r-- | net/sched/sch_gred.c | 16 | ||||
-rw-r--r-- | net/sched/sch_hfsc.c | 14 | ||||
-rw-r--r-- | net/sched/sch_htb.c | 17 | ||||
-rw-r--r-- | net/sched/sch_netem.c | 19 | ||||
-rw-r--r-- | net/sched/sch_red.c | 11 | ||||
-rw-r--r-- | net/sched/sch_tbf.c | 11 |
9 files changed, 87 insertions, 93 deletions
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 0c71f2eb96bc..335273416384 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
@@ -195,6 +195,11 @@ static const u8 llc_oui_ip[] = { | |||
195 | 0x08, 0x00 | 195 | 0x08, 0x00 |
196 | }; /* Ethertype IP (0800) */ | 196 | }; /* Ethertype IP (0800) */ |
197 | 197 | ||
198 | static const struct nla_policy atm_policy[TCA_ATM_MAX + 1] = { | ||
199 | [TCA_ATM_FD] = { .type = NLA_U32 }, | ||
200 | [TCA_ATM_EXCESS] = { .type = NLA_U32 }, | ||
201 | }; | ||
202 | |||
198 | static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, | 203 | static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, |
199 | struct nlattr **tca, unsigned long *arg) | 204 | struct nlattr **tca, unsigned long *arg) |
200 | { | 205 | { |
@@ -225,11 +230,12 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, | |||
225 | return -EBUSY; | 230 | return -EBUSY; |
226 | if (opt == NULL) | 231 | if (opt == NULL) |
227 | return -EINVAL; | 232 | return -EINVAL; |
228 | error = nla_parse_nested(tb, TCA_ATM_MAX, opt, NULL); | 233 | |
234 | error = nla_parse_nested(tb, TCA_ATM_MAX, opt, atm_policy); | ||
229 | if (error < 0) | 235 | if (error < 0) |
230 | return error; | 236 | return error; |
231 | 237 | ||
232 | if (!tb[TCA_ATM_FD] || nla_len(tb[TCA_ATM_FD]) < sizeof(fd)) | 238 | if (!tb[TCA_ATM_FD]) |
233 | return -EINVAL; | 239 | return -EINVAL; |
234 | fd = nla_get_u32(tb[TCA_ATM_FD]); | 240 | fd = nla_get_u32(tb[TCA_ATM_FD]); |
235 | pr_debug("atm_tc_change: fd %d\n", fd); | 241 | pr_debug("atm_tc_change: fd %d\n", fd); |
@@ -243,8 +249,6 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, | |||
243 | if (!tb[TCA_ATM_EXCESS]) | 249 | if (!tb[TCA_ATM_EXCESS]) |
244 | excess = NULL; | 250 | excess = NULL; |
245 | else { | 251 | else { |
246 | if (nla_len(tb[TCA_ATM_EXCESS]) != sizeof(u32)) | ||
247 | return -EINVAL; | ||
248 | excess = (struct atm_flow_data *) | 252 | excess = (struct atm_flow_data *) |
249 | atm_tc_get(sch, nla_get_u32(tb[TCA_ATM_EXCESS])); | 253 | atm_tc_get(sch, nla_get_u32(tb[TCA_ATM_EXCESS])); |
250 | if (!excess) | 254 | if (!excess) |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index da0f6c0152de..09969c1fbc08 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -1377,6 +1377,16 @@ static int cbq_set_fopt(struct cbq_class *cl, struct tc_cbq_fopt *fopt) | |||
1377 | return 0; | 1377 | return 0; |
1378 | } | 1378 | } |
1379 | 1379 | ||
1380 | static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = { | ||
1381 | [TCA_CBQ_LSSOPT] = { .len = sizeof(struct tc_cbq_lssopt) }, | ||
1382 | [TCA_CBQ_WRROPT] = { .len = sizeof(struct tc_cbq_wrropt) }, | ||
1383 | [TCA_CBQ_FOPT] = { .len = sizeof(struct tc_cbq_fopt) }, | ||
1384 | [TCA_CBQ_OVL_STRATEGY] = { .len = sizeof(struct tc_cbq_ovl) }, | ||
1385 | [TCA_CBQ_RATE] = { .len = sizeof(struct tc_ratespec) }, | ||
1386 | [TCA_CBQ_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, | ||
1387 | [TCA_CBQ_POLICE] = { .len = sizeof(struct tc_cbq_police) }, | ||
1388 | }; | ||
1389 | |||
1380 | static int cbq_init(struct Qdisc *sch, struct nlattr *opt) | 1390 | static int cbq_init(struct Qdisc *sch, struct nlattr *opt) |
1381 | { | 1391 | { |
1382 | struct cbq_sched_data *q = qdisc_priv(sch); | 1392 | struct cbq_sched_data *q = qdisc_priv(sch); |
@@ -1384,16 +1394,11 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt) | |||
1384 | struct tc_ratespec *r; | 1394 | struct tc_ratespec *r; |
1385 | int err; | 1395 | int err; |
1386 | 1396 | ||
1387 | err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL); | 1397 | err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy); |
1388 | if (err < 0) | 1398 | if (err < 0) |
1389 | return err; | 1399 | return err; |
1390 | 1400 | ||
1391 | if (tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL || | 1401 | if (tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL) |
1392 | nla_len(tb[TCA_CBQ_RATE]) < sizeof(struct tc_ratespec)) | ||
1393 | return -EINVAL; | ||
1394 | |||
1395 | if (tb[TCA_CBQ_LSSOPT] && | ||
1396 | nla_len(tb[TCA_CBQ_LSSOPT]) < sizeof(struct tc_cbq_lssopt)) | ||
1397 | return -EINVAL; | 1402 | return -EINVAL; |
1398 | 1403 | ||
1399 | r = nla_data(tb[TCA_CBQ_RATE]); | 1404 | r = nla_data(tb[TCA_CBQ_RATE]); |
@@ -1771,36 +1776,10 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t | |||
1771 | if (opt == NULL) | 1776 | if (opt == NULL) |
1772 | return -EINVAL; | 1777 | return -EINVAL; |
1773 | 1778 | ||
1774 | err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL); | 1779 | err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy); |
1775 | if (err < 0) | 1780 | if (err < 0) |
1776 | return err; | 1781 | return err; |
1777 | 1782 | ||
1778 | if (tb[TCA_CBQ_OVL_STRATEGY] && | ||
1779 | nla_len(tb[TCA_CBQ_OVL_STRATEGY]) < sizeof(struct tc_cbq_ovl)) | ||
1780 | return -EINVAL; | ||
1781 | |||
1782 | if (tb[TCA_CBQ_FOPT] && | ||
1783 | nla_len(tb[TCA_CBQ_FOPT]) < sizeof(struct tc_cbq_fopt)) | ||
1784 | return -EINVAL; | ||
1785 | |||
1786 | if (tb[TCA_CBQ_RATE] && | ||
1787 | nla_len(tb[TCA_CBQ_RATE]) < sizeof(struct tc_ratespec)) | ||
1788 | return -EINVAL; | ||
1789 | |||
1790 | if (tb[TCA_CBQ_LSSOPT] && | ||
1791 | nla_len(tb[TCA_CBQ_LSSOPT]) < sizeof(struct tc_cbq_lssopt)) | ||
1792 | return -EINVAL; | ||
1793 | |||
1794 | if (tb[TCA_CBQ_WRROPT] && | ||
1795 | nla_len(tb[TCA_CBQ_WRROPT]) < sizeof(struct tc_cbq_wrropt)) | ||
1796 | return -EINVAL; | ||
1797 | |||
1798 | #ifdef CONFIG_NET_CLS_ACT | ||
1799 | if (tb[TCA_CBQ_POLICE] && | ||
1800 | nla_len(tb[TCA_CBQ_POLICE]) < sizeof(struct tc_cbq_police)) | ||
1801 | return -EINVAL; | ||
1802 | #endif | ||
1803 | |||
1804 | if (cl) { | 1783 | if (cl) { |
1805 | /* Check parent */ | 1784 | /* Check parent */ |
1806 | if (parentid) { | 1785 | if (parentid) { |
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index f1d0a08aca75..0df911fd67b1 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
@@ -99,6 +99,14 @@ static void dsmark_put(struct Qdisc *sch, unsigned long cl) | |||
99 | { | 99 | { |
100 | } | 100 | } |
101 | 101 | ||
102 | static const struct nla_policy dsmark_policy[TCA_DSMARK_MAX + 1] = { | ||
103 | [TCA_DSMARK_INDICES] = { .type = NLA_U16 }, | ||
104 | [TCA_DSMARK_DEFAULT_INDEX] = { .type = NLA_U16 }, | ||
105 | [TCA_DSMARK_SET_TC_INDEX] = { .type = NLA_FLAG }, | ||
106 | [TCA_DSMARK_MASK] = { .type = NLA_U8 }, | ||
107 | [TCA_DSMARK_VALUE] = { .type = NLA_U8 }, | ||
108 | }; | ||
109 | |||
102 | static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, | 110 | static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, |
103 | struct nlattr **tca, unsigned long *arg) | 111 | struct nlattr **tca, unsigned long *arg) |
104 | { | 112 | { |
@@ -119,21 +127,15 @@ static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, | |||
119 | if (!opt) | 127 | if (!opt) |
120 | goto errout; | 128 | goto errout; |
121 | 129 | ||
122 | err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL); | 130 | err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, dsmark_policy); |
123 | if (err < 0) | 131 | if (err < 0) |
124 | return err; | 132 | goto errout; |
125 | 133 | ||
126 | err = -EINVAL; | 134 | if (tb[TCA_DSMARK_MASK]) |
127 | if (tb[TCA_DSMARK_MASK]) { | ||
128 | if (nla_len(tb[TCA_DSMARK_MASK]) < sizeof(u8)) | ||
129 | goto errout; | ||
130 | mask = nla_get_u8(tb[TCA_DSMARK_MASK]); | 135 | mask = nla_get_u8(tb[TCA_DSMARK_MASK]); |
131 | } | 136 | |
132 | if (tb[TCA_DSMARK_VALUE]) { | 137 | if (tb[TCA_DSMARK_VALUE]) |
133 | if (nla_len(tb[TCA_DSMARK_VALUE]) < sizeof(u8)) | ||
134 | goto errout; | ||
135 | p->value[*arg-1] = nla_get_u8(tb[TCA_DSMARK_VALUE]); | 138 | p->value[*arg-1] = nla_get_u8(tb[TCA_DSMARK_VALUE]); |
136 | } | ||
137 | 139 | ||
138 | if (tb[TCA_DSMARK_MASK]) | 140 | if (tb[TCA_DSMARK_MASK]) |
139 | p->mask[*arg-1] = mask; | 141 | p->mask[*arg-1] = mask; |
@@ -359,23 +361,18 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt) | |||
359 | if (!opt) | 361 | if (!opt) |
360 | goto errout; | 362 | goto errout; |
361 | 363 | ||
362 | err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL); | 364 | err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, dsmark_policy); |
363 | if (err < 0) | 365 | if (err < 0) |
364 | goto errout; | 366 | goto errout; |
365 | 367 | ||
366 | err = -EINVAL; | 368 | err = -EINVAL; |
367 | if (nla_len(tb[TCA_DSMARK_INDICES]) < sizeof(u16)) | ||
368 | goto errout; | ||
369 | indices = nla_get_u16(tb[TCA_DSMARK_INDICES]); | 369 | indices = nla_get_u16(tb[TCA_DSMARK_INDICES]); |
370 | 370 | ||
371 | if (hweight32(indices) != 1) | 371 | if (hweight32(indices) != 1) |
372 | goto errout; | 372 | goto errout; |
373 | 373 | ||
374 | if (tb[TCA_DSMARK_DEFAULT_INDEX]) { | 374 | if (tb[TCA_DSMARK_DEFAULT_INDEX]) |
375 | if (nla_len(tb[TCA_DSMARK_DEFAULT_INDEX]) < sizeof(u16)) | ||
376 | goto errout; | ||
377 | default_index = nla_get_u16(tb[TCA_DSMARK_DEFAULT_INDEX]); | 375 | default_index = nla_get_u16(tb[TCA_DSMARK_DEFAULT_INDEX]); |
378 | } | ||
379 | 376 | ||
380 | mask = kmalloc(indices * 2, GFP_KERNEL); | 377 | mask = kmalloc(indices * 2, GFP_KERNEL); |
381 | if (mask == NULL) { | 378 | if (mask == NULL) { |
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 365c7d8b17ab..3a9d226ff1e4 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -356,7 +356,7 @@ static inline int gred_change_table_def(struct Qdisc *sch, struct nlattr *dps) | |||
356 | struct tc_gred_sopt *sopt; | 356 | struct tc_gred_sopt *sopt; |
357 | int i; | 357 | int i; |
358 | 358 | ||
359 | if (dps == NULL || nla_len(dps) < sizeof(*sopt)) | 359 | if (dps == NULL) |
360 | return -EINVAL; | 360 | return -EINVAL; |
361 | 361 | ||
362 | sopt = nla_data(dps); | 362 | sopt = nla_data(dps); |
@@ -425,6 +425,12 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp, | |||
425 | return 0; | 425 | return 0; |
426 | } | 426 | } |
427 | 427 | ||
428 | static const struct nla_policy gred_policy[TCA_GRED_MAX + 1] = { | ||
429 | [TCA_GRED_PARMS] = { .len = sizeof(struct tc_gred_qopt) }, | ||
430 | [TCA_GRED_STAB] = { .len = 256 }, | ||
431 | [TCA_GRED_DPS] = { .len = sizeof(struct tc_gred_sopt) }, | ||
432 | }; | ||
433 | |||
428 | static int gred_change(struct Qdisc *sch, struct nlattr *opt) | 434 | static int gred_change(struct Qdisc *sch, struct nlattr *opt) |
429 | { | 435 | { |
430 | struct gred_sched *table = qdisc_priv(sch); | 436 | struct gred_sched *table = qdisc_priv(sch); |
@@ -436,7 +442,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
436 | if (opt == NULL) | 442 | if (opt == NULL) |
437 | return -EINVAL; | 443 | return -EINVAL; |
438 | 444 | ||
439 | err = nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL); | 445 | err = nla_parse_nested(tb, TCA_GRED_MAX, opt, gred_policy); |
440 | if (err < 0) | 446 | if (err < 0) |
441 | return err; | 447 | return err; |
442 | 448 | ||
@@ -444,9 +450,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
444 | return gred_change_table_def(sch, opt); | 450 | return gred_change_table_def(sch, opt); |
445 | 451 | ||
446 | if (tb[TCA_GRED_PARMS] == NULL || | 452 | if (tb[TCA_GRED_PARMS] == NULL || |
447 | nla_len(tb[TCA_GRED_PARMS]) < sizeof(*ctl) || | 453 | tb[TCA_GRED_STAB] == NULL) |
448 | tb[TCA_GRED_STAB] == NULL || | ||
449 | nla_len(tb[TCA_GRED_STAB]) < 256) | ||
450 | return -EINVAL; | 454 | return -EINVAL; |
451 | 455 | ||
452 | err = -EINVAL; | 456 | err = -EINVAL; |
@@ -499,7 +503,7 @@ static int gred_init(struct Qdisc *sch, struct nlattr *opt) | |||
499 | if (opt == NULL) | 503 | if (opt == NULL) |
500 | return -EINVAL; | 504 | return -EINVAL; |
501 | 505 | ||
502 | err = nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL); | 506 | err = nla_parse_nested(tb, TCA_GRED_MAX, opt, gred_policy); |
503 | if (err < 0) | 507 | if (err < 0) |
504 | return err; | 508 | return err; |
505 | 509 | ||
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 10a2f35a27a8..87293d0db1d7 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
@@ -986,6 +986,12 @@ hfsc_change_usc(struct hfsc_class *cl, struct tc_service_curve *usc, | |||
986 | cl->cl_flags |= HFSC_USC; | 986 | cl->cl_flags |= HFSC_USC; |
987 | } | 987 | } |
988 | 988 | ||
989 | static const struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = { | ||
990 | [TCA_HFSC_RSC] = { .len = sizeof(struct tc_service_curve) }, | ||
991 | [TCA_HFSC_FSC] = { .len = sizeof(struct tc_service_curve) }, | ||
992 | [TCA_HFSC_USC] = { .len = sizeof(struct tc_service_curve) }, | ||
993 | }; | ||
994 | |||
989 | static int | 995 | static int |
990 | hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | 996 | hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, |
991 | struct nlattr **tca, unsigned long *arg) | 997 | struct nlattr **tca, unsigned long *arg) |
@@ -1002,29 +1008,23 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
1002 | if (opt == NULL) | 1008 | if (opt == NULL) |
1003 | return -EINVAL; | 1009 | return -EINVAL; |
1004 | 1010 | ||
1005 | err = nla_parse_nested(tb, TCA_HFSC_MAX, opt, NULL); | 1011 | err = nla_parse_nested(tb, TCA_HFSC_MAX, opt, hfsc_policy); |
1006 | if (err < 0) | 1012 | if (err < 0) |
1007 | return err; | 1013 | return err; |
1008 | 1014 | ||
1009 | if (tb[TCA_HFSC_RSC]) { | 1015 | if (tb[TCA_HFSC_RSC]) { |
1010 | if (nla_len(tb[TCA_HFSC_RSC]) < sizeof(*rsc)) | ||
1011 | return -EINVAL; | ||
1012 | rsc = nla_data(tb[TCA_HFSC_RSC]); | 1016 | rsc = nla_data(tb[TCA_HFSC_RSC]); |
1013 | if (rsc->m1 == 0 && rsc->m2 == 0) | 1017 | if (rsc->m1 == 0 && rsc->m2 == 0) |
1014 | rsc = NULL; | 1018 | rsc = NULL; |
1015 | } | 1019 | } |
1016 | 1020 | ||
1017 | if (tb[TCA_HFSC_FSC]) { | 1021 | if (tb[TCA_HFSC_FSC]) { |
1018 | if (nla_len(tb[TCA_HFSC_FSC]) < sizeof(*fsc)) | ||
1019 | return -EINVAL; | ||
1020 | fsc = nla_data(tb[TCA_HFSC_FSC]); | 1022 | fsc = nla_data(tb[TCA_HFSC_FSC]); |
1021 | if (fsc->m1 == 0 && fsc->m2 == 0) | 1023 | if (fsc->m1 == 0 && fsc->m2 == 0) |
1022 | fsc = NULL; | 1024 | fsc = NULL; |
1023 | } | 1025 | } |
1024 | 1026 | ||
1025 | if (tb[TCA_HFSC_USC]) { | 1027 | if (tb[TCA_HFSC_USC]) { |
1026 | if (nla_len(tb[TCA_HFSC_USC]) < sizeof(*usc)) | ||
1027 | return -EINVAL; | ||
1028 | usc = nla_data(tb[TCA_HFSC_USC]); | 1028 | usc = nla_data(tb[TCA_HFSC_USC]); |
1029 | if (usc->m1 == 0 && usc->m2 == 0) | 1029 | if (usc->m1 == 0 && usc->m2 == 0) |
1030 | usc = NULL; | 1030 | usc = NULL; |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 69fac320f8bc..e1a579efc215 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -992,6 +992,13 @@ static void htb_reset(struct Qdisc *sch) | |||
992 | INIT_LIST_HEAD(q->drops + i); | 992 | INIT_LIST_HEAD(q->drops + i); |
993 | } | 993 | } |
994 | 994 | ||
995 | static const struct nla_policy htb_policy[TCA_HTB_MAX + 1] = { | ||
996 | [TCA_HTB_PARMS] = { .len = sizeof(struct tc_htb_opt) }, | ||
997 | [TCA_HTB_INIT] = { .len = sizeof(struct tc_htb_glob) }, | ||
998 | [TCA_HTB_CTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, | ||
999 | [TCA_HTB_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, | ||
1000 | }; | ||
1001 | |||
995 | static int htb_init(struct Qdisc *sch, struct nlattr *opt) | 1002 | static int htb_init(struct Qdisc *sch, struct nlattr *opt) |
996 | { | 1003 | { |
997 | struct htb_sched *q = qdisc_priv(sch); | 1004 | struct htb_sched *q = qdisc_priv(sch); |
@@ -1003,12 +1010,11 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) | |||
1003 | if (!opt) | 1010 | if (!opt) |
1004 | return -EINVAL; | 1011 | return -EINVAL; |
1005 | 1012 | ||
1006 | err = nla_parse_nested(tb, TCA_HTB_INIT, opt, NULL); | 1013 | err = nla_parse_nested(tb, TCA_HTB_INIT, opt, htb_policy); |
1007 | if (err < 0) | 1014 | if (err < 0) |
1008 | return err; | 1015 | return err; |
1009 | 1016 | ||
1010 | if (tb[TCA_HTB_INIT] == NULL || | 1017 | if (tb[TCA_HTB_INIT] == NULL) { |
1011 | nla_len(tb[TCA_HTB_INIT]) < sizeof(*gopt)) { | ||
1012 | printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n"); | 1018 | printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n"); |
1013 | return -EINVAL; | 1019 | return -EINVAL; |
1014 | } | 1020 | } |
@@ -1319,13 +1325,12 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1319 | if (!opt) | 1325 | if (!opt) |
1320 | goto failure; | 1326 | goto failure; |
1321 | 1327 | ||
1322 | err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, NULL); | 1328 | err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, htb_policy); |
1323 | if (err < 0) | 1329 | if (err < 0) |
1324 | goto failure; | 1330 | goto failure; |
1325 | 1331 | ||
1326 | err = -EINVAL; | 1332 | err = -EINVAL; |
1327 | if (tb[TCA_HTB_PARMS] == NULL || | 1333 | if (tb[TCA_HTB_PARMS] == NULL) |
1328 | nla_len(tb[TCA_HTB_PARMS]) < sizeof(*hopt)) | ||
1329 | goto failure; | 1334 | goto failure; |
1330 | 1335 | ||
1331 | parent = parentid == TC_H_ROOT ? NULL : htb_find(parentid, sch); | 1336 | parent = parentid == TC_H_ROOT ? NULL : htb_find(parentid, sch); |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 1a755799ffb8..c9c649b26eaa 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -368,9 +368,6 @@ static int get_correlation(struct Qdisc *sch, const struct nlattr *attr) | |||
368 | struct netem_sched_data *q = qdisc_priv(sch); | 368 | struct netem_sched_data *q = qdisc_priv(sch); |
369 | const struct tc_netem_corr *c = nla_data(attr); | 369 | const struct tc_netem_corr *c = nla_data(attr); |
370 | 370 | ||
371 | if (nla_len(attr) != sizeof(*c)) | ||
372 | return -EINVAL; | ||
373 | |||
374 | init_crandom(&q->delay_cor, c->delay_corr); | 371 | init_crandom(&q->delay_cor, c->delay_corr); |
375 | init_crandom(&q->loss_cor, c->loss_corr); | 372 | init_crandom(&q->loss_cor, c->loss_corr); |
376 | init_crandom(&q->dup_cor, c->dup_corr); | 373 | init_crandom(&q->dup_cor, c->dup_corr); |
@@ -382,9 +379,6 @@ static int get_reorder(struct Qdisc *sch, const struct nlattr *attr) | |||
382 | struct netem_sched_data *q = qdisc_priv(sch); | 379 | struct netem_sched_data *q = qdisc_priv(sch); |
383 | const struct tc_netem_reorder *r = nla_data(attr); | 380 | const struct tc_netem_reorder *r = nla_data(attr); |
384 | 381 | ||
385 | if (nla_len(attr) != sizeof(*r)) | ||
386 | return -EINVAL; | ||
387 | |||
388 | q->reorder = r->probability; | 382 | q->reorder = r->probability; |
389 | init_crandom(&q->reorder_cor, r->correlation); | 383 | init_crandom(&q->reorder_cor, r->correlation); |
390 | return 0; | 384 | return 0; |
@@ -395,14 +389,17 @@ static int get_corrupt(struct Qdisc *sch, const struct nlattr *attr) | |||
395 | struct netem_sched_data *q = qdisc_priv(sch); | 389 | struct netem_sched_data *q = qdisc_priv(sch); |
396 | const struct tc_netem_corrupt *r = nla_data(attr); | 390 | const struct tc_netem_corrupt *r = nla_data(attr); |
397 | 391 | ||
398 | if (nla_len(attr) != sizeof(*r)) | ||
399 | return -EINVAL; | ||
400 | |||
401 | q->corrupt = r->probability; | 392 | q->corrupt = r->probability; |
402 | init_crandom(&q->corrupt_cor, r->correlation); | 393 | init_crandom(&q->corrupt_cor, r->correlation); |
403 | return 0; | 394 | return 0; |
404 | } | 395 | } |
405 | 396 | ||
397 | static const struct nla_policy netem_policy[TCA_NETEM_MAX + 1] = { | ||
398 | [TCA_NETEM_CORR] = { .len = sizeof(struct tc_netem_corr) }, | ||
399 | [TCA_NETEM_REORDER] = { .len = sizeof(struct tc_netem_reorder) }, | ||
400 | [TCA_NETEM_CORRUPT] = { .len = sizeof(struct tc_netem_corrupt) }, | ||
401 | }; | ||
402 | |||
406 | /* Parse netlink message to set options */ | 403 | /* Parse netlink message to set options */ |
407 | static int netem_change(struct Qdisc *sch, struct nlattr *opt) | 404 | static int netem_change(struct Qdisc *sch, struct nlattr *opt) |
408 | { | 405 | { |
@@ -414,8 +411,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt) | |||
414 | if (opt == NULL) | 411 | if (opt == NULL) |
415 | return -EINVAL; | 412 | return -EINVAL; |
416 | 413 | ||
417 | ret = nla_parse_nested_compat(tb, TCA_NETEM_MAX, opt, NULL, qopt, | 414 | ret = nla_parse_nested_compat(tb, TCA_NETEM_MAX, opt, netem_policy, |
418 | sizeof(*qopt)); | 415 | qopt, sizeof(*qopt)); |
419 | if (ret < 0) | 416 | if (ret < 0) |
420 | return ret; | 417 | return ret; |
421 | 418 | ||
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index dcf6afc196f8..3dcd493f4f4a 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
@@ -201,6 +201,11 @@ static struct Qdisc *red_create_dflt(struct Qdisc *sch, u32 limit) | |||
201 | return NULL; | 201 | return NULL; |
202 | } | 202 | } |
203 | 203 | ||
204 | static const struct nla_policy red_policy[TCA_RED_MAX + 1] = { | ||
205 | [TCA_RED_PARMS] = { .len = sizeof(struct tc_red_qopt) }, | ||
206 | [TCA_RED_STAB] = { .len = RED_STAB_SIZE }, | ||
207 | }; | ||
208 | |||
204 | static int red_change(struct Qdisc *sch, struct nlattr *opt) | 209 | static int red_change(struct Qdisc *sch, struct nlattr *opt) |
205 | { | 210 | { |
206 | struct red_sched_data *q = qdisc_priv(sch); | 211 | struct red_sched_data *q = qdisc_priv(sch); |
@@ -212,14 +217,12 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt) | |||
212 | if (opt == NULL) | 217 | if (opt == NULL) |
213 | return -EINVAL; | 218 | return -EINVAL; |
214 | 219 | ||
215 | err = nla_parse_nested(tb, TCA_RED_MAX, opt, NULL); | 220 | err = nla_parse_nested(tb, TCA_RED_MAX, opt, red_policy); |
216 | if (err < 0) | 221 | if (err < 0) |
217 | return err; | 222 | return err; |
218 | 223 | ||
219 | if (tb[TCA_RED_PARMS] == NULL || | 224 | if (tb[TCA_RED_PARMS] == NULL || |
220 | nla_len(tb[TCA_RED_PARMS]) < sizeof(*ctl) || | 225 | tb[TCA_RED_STAB] == NULL) |
221 | tb[TCA_RED_STAB] == NULL || | ||
222 | nla_len(tb[TCA_RED_STAB]) < RED_STAB_SIZE) | ||
223 | return -EINVAL; | 226 | return -EINVAL; |
224 | 227 | ||
225 | ctl = nla_data(tb[TCA_RED_PARMS]); | 228 | ctl = nla_data(tb[TCA_RED_PARMS]); |
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index b7a185dc3def..0b7d78f59d8c 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
@@ -270,6 +270,12 @@ static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit) | |||
270 | return NULL; | 270 | return NULL; |
271 | } | 271 | } |
272 | 272 | ||
273 | static const struct nla_policy tbf_policy[TCA_TBF_MAX + 1] = { | ||
274 | [TCA_TBF_PARMS] = { .len = sizeof(struct tc_tbf_qopt) }, | ||
275 | [TCA_TBF_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, | ||
276 | [TCA_TBF_PTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, | ||
277 | }; | ||
278 | |||
273 | static int tbf_change(struct Qdisc* sch, struct nlattr *opt) | 279 | static int tbf_change(struct Qdisc* sch, struct nlattr *opt) |
274 | { | 280 | { |
275 | int err; | 281 | int err; |
@@ -281,13 +287,12 @@ static int tbf_change(struct Qdisc* sch, struct nlattr *opt) | |||
281 | struct Qdisc *child = NULL; | 287 | struct Qdisc *child = NULL; |
282 | int max_size,n; | 288 | int max_size,n; |
283 | 289 | ||
284 | err = nla_parse_nested(tb, TCA_TBF_PTAB, opt, NULL); | 290 | err = nla_parse_nested(tb, TCA_TBF_PTAB, opt, tbf_policy); |
285 | if (err < 0) | 291 | if (err < 0) |
286 | return err; | 292 | return err; |
287 | 293 | ||
288 | err = -EINVAL; | 294 | err = -EINVAL; |
289 | if (tb[TCA_TBF_PARMS] == NULL || | 295 | if (tb[TCA_TBF_PARMS] == NULL) |
290 | nla_len(tb[TCA_TBF_PARMS]) < sizeof(*qopt)) | ||
291 | goto done; | 296 | goto done; |
292 | 297 | ||
293 | qopt = nla_data(tb[TCA_TBF_PARMS]); | 298 | qopt = nla_data(tb[TCA_TBF_PARMS]); |