diff options
author | Hiroaki SHIMODA <shimoda.hiroaki@gmail.com> | 2012-08-03 06:57:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-08-03 19:47:24 -0400 |
commit | 696ecdc10622d86541f2e35cc16e15b6b3b1b67e (patch) | |
tree | 55090a298a1e20df7aaf7c27af2505c2c581eac1 /net/sched | |
parent | f3f9f332e231abaf28e14344733b7d000b830f7c (diff) |
net_sched: gact: Fix potential panic in tcf_gact().
gact_rand array is accessed by gact->tcfg_ptype whose value
is assumed to less than MAX_RAND, but any range checks are
not performed.
So add a check in tcf_gact_init(). And in tcf_gact(), we can
reduce a branch.
Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/act_gact.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index f10fb8256442..05d60859d8e3 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
@@ -67,6 +67,9 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est, | |||
67 | struct tcf_common *pc; | 67 | struct tcf_common *pc; |
68 | int ret = 0; | 68 | int ret = 0; |
69 | int err; | 69 | int err; |
70 | #ifdef CONFIG_GACT_PROB | ||
71 | struct tc_gact_p *p_parm = NULL; | ||
72 | #endif | ||
70 | 73 | ||
71 | if (nla == NULL) | 74 | if (nla == NULL) |
72 | return -EINVAL; | 75 | return -EINVAL; |
@@ -82,6 +85,12 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est, | |||
82 | #ifndef CONFIG_GACT_PROB | 85 | #ifndef CONFIG_GACT_PROB |
83 | if (tb[TCA_GACT_PROB] != NULL) | 86 | if (tb[TCA_GACT_PROB] != NULL) |
84 | return -EOPNOTSUPP; | 87 | return -EOPNOTSUPP; |
88 | #else | ||
89 | if (tb[TCA_GACT_PROB]) { | ||
90 | p_parm = nla_data(tb[TCA_GACT_PROB]); | ||
91 | if (p_parm->ptype >= MAX_RAND) | ||
92 | return -EINVAL; | ||
93 | } | ||
85 | #endif | 94 | #endif |
86 | 95 | ||
87 | pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info); | 96 | pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info); |
@@ -103,8 +112,7 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est, | |||
103 | spin_lock_bh(&gact->tcf_lock); | 112 | spin_lock_bh(&gact->tcf_lock); |
104 | gact->tcf_action = parm->action; | 113 | gact->tcf_action = parm->action; |
105 | #ifdef CONFIG_GACT_PROB | 114 | #ifdef CONFIG_GACT_PROB |
106 | if (tb[TCA_GACT_PROB] != NULL) { | 115 | if (p_parm) { |
107 | struct tc_gact_p *p_parm = nla_data(tb[TCA_GACT_PROB]); | ||
108 | gact->tcfg_paction = p_parm->paction; | 116 | gact->tcfg_paction = p_parm->paction; |
109 | gact->tcfg_pval = p_parm->pval; | 117 | gact->tcfg_pval = p_parm->pval; |
110 | gact->tcfg_ptype = p_parm->ptype; | 118 | gact->tcfg_ptype = p_parm->ptype; |
@@ -133,7 +141,7 @@ static int tcf_gact(struct sk_buff *skb, const struct tc_action *a, | |||
133 | 141 | ||
134 | spin_lock(&gact->tcf_lock); | 142 | spin_lock(&gact->tcf_lock); |
135 | #ifdef CONFIG_GACT_PROB | 143 | #ifdef CONFIG_GACT_PROB |
136 | if (gact->tcfg_ptype && gact_rand[gact->tcfg_ptype] != NULL) | 144 | if (gact->tcfg_ptype) |
137 | action = gact_rand[gact->tcfg_ptype](gact); | 145 | action = gact_rand[gact->tcfg_ptype](gact); |
138 | else | 146 | else |
139 | action = gact->tcf_action; | 147 | action = gact->tcf_action; |