Message ID | 20090526195840.8464.36548.stgit@menage.mtv.corp.google.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
On Tue, 26 May 2009 12:59:11 -0700 Paul Menage <menage@google.com> wrote: > Avoid reading the unsynchronized value cs->classid multiple times, > since it could change concurrently from non-zero to zero; this would > result in the classifier returning a positive result with a bogus > (zero) classid. When this race occurs, what are the user-visible consequences? People who need to decide to which kernels a patch should be applied like to know such things. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, May 26, 2009 at 2:04 PM, Andrew Morton <akpm@linux-foundation.org> wrote: > On Tue, 26 May 2009 12:59:11 -0700 > Paul Menage <menage@google.com> wrote: > >> Avoid reading the unsynchronized value cs->classid multiple times, >> since it could change concurrently from non-zero to zero; this would >> result in the classifier returning a positive result with a bogus >> (zero) classid. > > When this race occurs, what are the user-visible consequences? My guess is very little - rather than returning -1 to indicate that there's no classid associated with the flow, we're returning a positive response that the classid is 0. I don't know the network scheduling code well enough to predict what effect that would have, but I'd guess it results in the subsequent classid->queue lookup failing and the packet being shunted down some default queue (unless the user happens to have set up a queue with id 0). But the race looks to be against the intent of the code, which is to return -1 if the classid is 0, or fill in the res struct if it's non-zero. > > People who need to decide to which kernels a patch should be applied > like to know such things. > I don't think this is a -stable candidate. Paul -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Paul Menage <menage@google.com> Date: Tue, 26 May 2009 12:59:11 -0700 > cls_cgroup: read classid atomically in classifier > > Avoid reading the unsynchronized value cs->classid multiple times, > since it could change concurrently from non-zero to zero; this would > result in the classifier returning a positive result with a bogus > (zero) classid. > > Signed-off-by: Paul Menage <menage@google.com> > Reviewed-by: Li Zefan <lizf@cn.fujitsu.com> Patch applied, thanks! -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 1ab4542..0f815cc 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -98,8 +98,7 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_result *res) { struct cls_cgroup_head *head = tp->root; - struct cgroup_cls_state *cs; - int ret = 0; + u32 classid; /* * Due to the nature of the classifier it is required to ignore all @@ -115,17 +114,18 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, return -1; rcu_read_lock(); - cs = task_cls_state(current); - if (cs->classid && tcf_em_tree_match(skb, &head->ematches, NULL)) { - res->classid = cs->classid; - res->class = 0; - ret = tcf_exts_exec(skb, &head->exts, res); - } else - ret = -1; - + classid = task_cls_state(current)->classid; rcu_read_unlock(); - return ret; + if (!classid) + return -1; + + if (!tcf_em_tree_match(skb, &head->ematches, NULL)) + return -1; + + res->classid = classid; + res->class = 0; + return tcf_exts_exec(skb, &head->exts, res); } static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle)