From patchwork Tue Jun 2 09:11:48 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Minoru Usui X-Patchwork-Id: 27946 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id AA4C7B707B for ; Tue, 2 Jun 2009 19:16:59 +1000 (EST) Received: by ozlabs.org (Postfix) id 9D052DDDFC; Tue, 2 Jun 2009 19:16:59 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 20307DDD1B for ; Tue, 2 Jun 2009 19:16:59 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754504AbZFBJQV (ORCPT ); Tue, 2 Jun 2009 05:16:21 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754068AbZFBJQU (ORCPT ); Tue, 2 Jun 2009 05:16:20 -0400 Received: from TYO201.gate.nec.co.jp ([202.32.8.193]:41055 "EHLO tyo201.gate.nec.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751644AbZFBJQU (ORCPT ); Tue, 2 Jun 2009 05:16:20 -0400 Received: from mailgate3.nec.co.jp ([10.7.69.161]) by tyo201.gate.nec.co.jp (8.13.8/8.13.4) with ESMTP id n529FTZl009668; Tue, 2 Jun 2009 18:15:29 +0900 (JST) Received: (from root@localhost) by mailgate3.nec.co.jp (8.11.7/3.7W-MAILGATE-NEC) id n529FTU00994; Tue, 2 Jun 2009 18:15:29 +0900 (JST) Received: from mail02.kamome.nec.co.jp (mail02.kamome.nec.co.jp [10.25.43.5]) by mailsv4.nec.co.jp (8.13.8/8.13.4) with ESMTP id n529FDMi015442; Tue, 2 Jun 2009 18:15:28 +0900 (JST) Received: from saigo.jp.nec.com ([10.26.220.6] [10.26.220.6]) by mail03.kamome.nec.co.jp with ESMTP id BT-MMP-732032; Tue, 2 Jun 2009 18:11:50 +0900 Received: from NES2061007292.nsl.ad.nec.co.jp ([10.21.43.215] [10.21.43.215]) by mail.jp.nec.com with ESMTP; Tue, 2 Jun 2009 18:11:49 +0900 Date: Tue, 2 Jun 2009 18:11:48 +0900 From: Minoru Usui To: netdev@vger.kernel.org, containers@lists.linux-foundation.org Cc: Jarek Poplawski , hadi@cyberus.ca Subject: [PATCH 1/1] net_cls: fix unconfigured struct tcf_proto keeps chaining and avoid kernel panic when we use cls_cgroup Message-Id: <20090602181148.e01f0417.usui@mxm.nes.nec.co.jp> X-Mailer: Sylpheed 2.6.0 (GTK+ 2.10.14; i686-pc-mingw32) Mime-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org net_cls: fix unconfigured struct tcf_proto keeps chaining and avoid kernel panic when we use cls_cgroup This patch fixes a bug which unconfigured struct tcf_proto keeps chaining in tc_ctl_tfilter(), and avoids kernel panic in cls_cgroup_classify() when we use cls_cgroup. When we execute 'tc filter add', tcf_proto is allocated, initialized by classifier's init(), and chained. After it's chained, tc_ctl_tfilter() calls classifier's change(). When classifier's change() fails, tc_ctl_tfilter() does not free and keeps tcf_proto. In addition, cls_cgroup is initialized in change() not in init(). It accesses unconfigured struct tcf_proto which is chained before change(), then hits Oops. Signed-off-by: Minoru Usui Signed-off-by: Jarek Poplawski Signed-off-by: Jamal Hadi Salim Tested-by: Minoru Usui diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 0759f32..09cdcdf 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -135,6 +135,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) unsigned long cl; unsigned long fh; int err; + int tp_created = 0; if (net != &init_net) return -EINVAL; @@ -266,10 +267,7 @@ replay: goto errout; } - spin_lock_bh(root_lock); - tp->next = *back; - *back = tp; - spin_unlock_bh(root_lock); + tp_created = 1; } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) goto errout; @@ -296,8 +294,11 @@ replay: switch (n->nlmsg_type) { case RTM_NEWTFILTER: err = -EEXIST; - if (n->nlmsg_flags & NLM_F_EXCL) + if (n->nlmsg_flags & NLM_F_EXCL) { + if (tp_created) + tcf_destroy(tp); goto errout; + } break; case RTM_DELTFILTER: err = tp->ops->delete(tp, fh); @@ -314,8 +315,18 @@ replay: } err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh); - if (err == 0) + if (err == 0) { + if (tp_created) { + spin_lock_bh(root_lock); + tp->next = *back; + *back = tp; + spin_unlock_bh(root_lock); + } tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); + } else { + if (tp_created) + tcf_destroy(tp); + } errout: if (cl)