| From 7312496e121a4b5e8ae09d71718c8651030295ca Mon Sep 17 00:00:00 2001 |
| From: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com> |
| Date: Fri, 3 Aug 2012 19:57:52 +0900 |
| Subject: [PATCH] net_sched: gact: Fix potential panic in tcf_gact(). |
| |
| commit 696ecdc10622d86541f2e35cc16e15b6b3b1b67e upstream. |
| |
| 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> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| net/sched/act_gact.c | 14 +++++++++++--- |
| 1 file changed, 11 insertions(+), 3 deletions(-) |
| |
| diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c |
| index f9fc6ec1fef6..faebd8a6da57 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, |
| struct tcf_common *pc; |
| int ret = 0; |
| int err; |
| +#ifdef CONFIG_GACT_PROB |
| + struct tc_gact_p *p_parm = NULL; |
| +#endif |
| |
| if (nla == NULL) |
| return -EINVAL; |
| @@ -82,6 +85,12 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est, |
| #ifndef CONFIG_GACT_PROB |
| if (tb[TCA_GACT_PROB] != NULL) |
| return -EOPNOTSUPP; |
| +#else |
| + if (tb[TCA_GACT_PROB]) { |
| + p_parm = nla_data(tb[TCA_GACT_PROB]); |
| + if (p_parm->ptype >= MAX_RAND) |
| + return -EINVAL; |
| + } |
| #endif |
| |
| 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, |
| spin_lock_bh(&gact->tcf_lock); |
| gact->tcf_action = parm->action; |
| #ifdef CONFIG_GACT_PROB |
| - if (tb[TCA_GACT_PROB] != NULL) { |
| - struct tc_gact_p *p_parm = nla_data(tb[TCA_GACT_PROB]); |
| + if (p_parm) { |
| gact->tcfg_paction = p_parm->paction; |
| gact->tcfg_pval = p_parm->pval; |
| gact->tcfg_ptype = p_parm->ptype; |
| @@ -132,7 +140,7 @@ static int tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result |
| |
| spin_lock(&gact->tcf_lock); |
| #ifdef CONFIG_GACT_PROB |
| - if (gact->tcfg_ptype && gact_rand[gact->tcfg_ptype] != NULL) |
| + if (gact->tcfg_ptype) |
| action = gact_rand[gact->tcfg_ptype](gact); |
| else |
| action = gact->tcf_action; |
| -- |
| 1.8.5.2 |
| |