All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vlad Buslov <vladbu@mellanox.com>
To: Davide Caratti <dcaratti@redhat.com>
Cc: "David S. Miller" <davem@davemloft.net>,
	Jamal Hadi Salim <jhs@mojatatu.com>,
	Cong Wang <xiyou.wangcong@gmail.com>,
	Jiri Pirko <jiri@resnulli.us>,
	"pabeni@redhat.com" <pabeni@redhat.com>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>
Subject: Re: [PATCH net 07/16] net/sched: act_connmark: validate the control action inside init()
Date: Fri, 1 Mar 2019 16:35:55 +0000	[thread overview]
Message-ID: <vbfimx2d02g.fsf@mellanox.com> (raw)
In-Reply-To: <89f95fccc16101df5d1b01c00957751e412439a5.1551288982.git.dcaratti@redhat.com>


On Wed 27 Feb 2019 at 17:40, Davide Caratti <dcaratti@redhat.com> wrote:
> the following script:
>
>  # tc qdisc add dev crash0 clsact
>  # tc filter add dev crash0 egress matchall \
>  > action connmark pass index 90
>  # tc actions replace action connmark \
>  > goto chain 42 index 90 cookie c1a0c1a0
>  # tc actions show action connmark
>
> had the following output:
>
>  Error: Failed to init TC action chain.
>  We have an error talking to the kernel
>  total acts 1
>
>          action order 0: connmark zone 0 goto chain 42
>           index 90 ref 2 bind 1
>          cookie c1a0c1a0
>
> Then, the first packet transmitted by crash0 made the kernel crash:
>
>  BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
>  #PF error: [normal kernel read fault]
>  PGD 0 P4D 0
>  Oops: 0000 [#1] SMP PTI
>  CPU: 0 PID: 302 Comm: kworker/0:2 Not tainted 5.0.0-rc4.gotochain_crash+ #533
>  Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
>  Workqueue: ipv6_addrconf addrconf_dad_work
>  RIP: 0010:tcf_action_exec+0xb8/0x100
>  Code: 00 00 00 20 74 1d 83 f8 03 75 09 49 83 c4 08 4d 39 ec 75 bc 48 83 c4 10 5b 5d 41 5c 41 5d 41 5e 41 5f c3 49 8b 97 a8 00 00 00 <48> 8b 12 48 89 55 00 48 83 c4 10 5b 5d 41 5c 41 5d 41 5e 41 5f c3
>  RSP: 0018:ffff9bea406c3ad0 EFLAGS: 00010246
>  RAX: 000000002000002a RBX: ffff8c5dfc009f00 RCX: 0000000000000000
>  RDX: 0000000000000000 RSI: ffff9bea406c3a80 RDI: ffff8c5dfb9d6ec0
>  RBP: ffff9bea406c3b70 R08: ffff8c5dfda222a0 R09: ffffffff90933c3c
>  R10: 0000000000000000 R11: 0000000092793f7d R12: ffff8c5df48b3c00
>  R13: ffff8c5df48b3c08 R14: 0000000000000001 R15: ffff8c5dfb9d6e40
>  FS:  0000000000000000(0000) GS:ffff8c5dfda00000(0000) knlGS:0000000000000000
>  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>  CR2: 0000000000000000 CR3: 0000000062e0e006 CR4: 00000000001606f0
>  Call Trace:
>   tcf_classify+0x58/0x120
>   __dev_queue_xmit+0x40a/0x890
>   ? ndisc_next_option+0x50/0x50
>   ? ___neigh_create+0x4d5/0x680
>   ? ip6_finish_output2+0x1b5/0x590
>   ip6_finish_output2+0x1b5/0x590
>   ? ip6_output+0x68/0x110
>   ip6_output+0x68/0x110
>   ? nf_hook.constprop.28+0x79/0xc0
>   ndisc_send_skb+0x248/0x2e0
>   ndisc_send_ns+0xf8/0x200
>   ? addrconf_dad_work+0x389/0x4b0
>   addrconf_dad_work+0x389/0x4b0
>   ? __switch_to_asm+0x34/0x70
>   ? process_one_work+0x195/0x380
>   ? addrconf_dad_completed+0x370/0x370
>   process_one_work+0x195/0x380
>   worker_thread+0x30/0x390
>   ? process_one_work+0x380/0x380
>   kthread+0x113/0x130
>   ? kthread_park+0x90/0x90
>   ret_from_fork+0x35/0x40
>  Modules linked in: act_connmark nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 veth ip6table_filter ip6_tables iptable_filter binfmt_misc ext4 crct10dif_pclmul mbcache crc32_pclmul jbd2 snd_hda_codec_generic ghash_clmulni_intel snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_seq snd_seq_device snd_pcm aesni_intel snd_timer crypto_simd cryptd snd glue_helper joydev virtio_balloon pcspkr soundcore i2c_piix4 nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables xfs ata_generic pata_acpi qxl drm_kms_helper virtio_net net_failover syscopyarea virtio_blk failover virtio_console sysfillrect sysimgblt fb_sys_fops ttm drm ata_piix crc32c_intel serio_raw libata virtio_pci virtio_ring virtio floppy dm_mirror dm_region_hash dm_log dm_mod
>  CR2: 0000000000000000
>
> Validating the control action within tcf_connmark_init() proved to fix the
> above issue. A TDC selftest is added to verify the correct behavior.
>
> Fixes: db50514f9a9c ("net: sched: add termination action to allow goto chain")
> Fixes: 97763dc0f401 ("net_sched: reject unknown tcfa_action values")
> Signed-off-by: Davide Caratti <dcaratti@redhat.com>
> ---
>  net/sched/act_connmark.c                      | 24 +++++++++++++++++-
>  .../tc-testing/tc-tests/actions/connmark.json | 25 +++++++++++++++++++
>  2 files changed, 48 insertions(+), 1 deletion(-)
>
> diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
> index 30c4c109c80c..5e02f9f6850a 100644
> --- a/net/sched/act_connmark.c
> +++ b/net/sched/act_connmark.c
> @@ -21,6 +21,7 @@
>  #include <net/netlink.h>
>  #include <net/pkt_sched.h>
>  #include <net/act_api.h>
> +#include <net/pkt_cls.h>
>  #include <uapi/linux/tc_act/tc_connmark.h>
>  #include <net/tc_act/tc_connmark.h>
>  
> @@ -101,10 +102,11 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
>  			     struct netlink_ext_ack *extack)
>  {
>  	struct tc_action_net *tn = net_generic(net, connmark_net_id);
> +	struct tcf_chain *newchain = NULL, *oldchain;
>  	struct nlattr *tb[TCA_CONNMARK_MAX + 1];
>  	struct tcf_connmark_info *ci;
>  	struct tc_connmark *parm;
> -	int ret = 0;
> +	int ret = 0, err;
>  
>  	if (!nla)
>  		return -EINVAL;
> @@ -129,6 +131,12 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
>  		}
>  
>  		ci = to_connmark(*a);
> +		err = tcf_action_check_ctrlact(parm->action, tp, &newchain,
> +					       extack);
> +		if (err)
> +			goto release_idr;
> +		oldchain = ci->tcf_goto_chain;
> +		ci->tcf_goto_chain = newchain;
>  		ci->tcf_action = parm->action;
>  		ci->net = net;
>  		ci->zone = parm->zone;
> @@ -143,15 +151,29 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
>  			tcf_idr_release(*a, bind);
>  			return -EEXIST;
>  		}
> +		err = tcf_action_check_ctrlact(parm->action, tp, &newchain,
> +					       extack);
> +		if (err)
> +			goto release_idr;
>  		/* replacing action and zone */
>  		spin_lock_bh(&ci->tcf_lock);
> +		oldchain = ci->tcf_goto_chain;
> +		ci->tcf_goto_chain = newchain;
>  		ci->tcf_action = parm->action;
>  		ci->zone = parm->zone;
>  		spin_unlock_bh(&ci->tcf_lock);
>  		ret = 0;
> +	} else {
> +		goto end;

Maybe just initialize oldchain to NULL to avoid this goto?

>  	}
>  
> +	if (oldchain)
> +		tcf_chain_put_by_act(oldchain);
> +end:
>  	return ret;
> +release_idr:
> +	tcf_idr_release(*a, bind);
> +	return err;
>  }
>  
>  static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
> diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json b/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json
> index 13147a1f5731..cadde8f41fcd 100644
> --- a/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json
> +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json
> @@ -287,5 +287,30 @@
>          "teardown": [
>              "$TC actions flush action connmark"
>          ]
> +    },
> +    {
> +        "id": "c506",
> +        "name": "Replace connmark with invalid goto chain control",
> +        "category": [
> +            "actions",
> +            "connmark"
> +        ],
> +        "setup": [
> +            [
> +                "$TC actions flush action connmark",
> +                0,
> +                1,
> +                255
> +            ],
> +            "$TC actions add action connmark pass index 90"
> +        ],
> +        "cmdUnderTest": "$TC actions replace action connmark goto chain 42 index 90 cookie c1a0c1a0",
> +        "expExitCode": "255",
> +        "verifyCmd": "$TC actions get action connmark index 90",
> +        "matchPattern": "action order [0-9]+: connmark zone 0 pass.*index 90 ref",
> +        "matchCount": "1",
> +        "teardown": [
> +            "$TC actions flush action connmark"
> +        ]
>      }
>  ]


  reply	other threads:[~2019-03-01 16:36 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-27 17:40 [PATCH net 00/16] validate the control action with all the other parameters Davide Caratti
2019-02-27 17:40 ` [PATCH net 01/16] net/sched: prepare TC actions to properly validate the control action Davide Caratti
2019-02-28  1:28   ` Cong Wang
2019-03-01 17:59     ` Davide Caratti
2019-02-27 17:40 ` [PATCH net 02/16] net/sched: act_bpf: validate the control action inside init() Davide Caratti
2019-02-27 17:40 ` [PATCH net 03/16] net/sched: act_csum: " Davide Caratti
2019-02-28  1:50   ` Cong Wang
2019-03-01 18:02     ` Davide Caratti
2019-03-02  0:04       ` Cong Wang
2019-03-07 13:56         ` Davide Caratti
2019-03-07 14:51           ` Vlad Buslov
2019-03-07 16:56             ` Davide Caratti
2019-03-08 17:47               ` Davide Caratti
2019-02-27 17:40 ` [PATCH net 04/16] net/sched: act_gact: " Davide Caratti
2019-02-27 17:40 ` [PATCH net 05/16] net/sched: act_ife: " Davide Caratti
2019-03-01 16:33   ` Vlad Buslov
2019-02-27 17:40 ` [PATCH net 06/16] net/sched: act_mirred: " Davide Caratti
2019-02-27 17:40 ` [PATCH net 07/16] net/sched: act_connmark: " Davide Caratti
2019-03-01 16:35   ` Vlad Buslov [this message]
2019-02-27 17:40 ` [PATCH net 08/16] net/sched: act_nat: " Davide Caratti
2019-02-27 17:40 ` [PATCH net 09/16] net/sched: act_pedit: " Davide Caratti
2019-02-27 17:40 ` [PATCH net 10/16] net/sched: act_police: " Davide Caratti
2019-02-27 17:40 ` [PATCH net 11/16] net/sched: act_sample: " Davide Caratti
2019-02-27 17:40 ` [PATCH net 12/16] net/sched: act_simple: " Davide Caratti
2019-03-01 16:39   ` Vlad Buslov
2019-02-27 17:40 ` [PATCH net 13/16] net/sched: act_skbedit: " Davide Caratti
2019-03-01 16:43   ` Vlad Buslov
2019-02-27 17:40 ` [PATCH net 14/16] net/sched: act_skbmod: " Davide Caratti
2019-02-27 17:40 ` [PATCH net 15/16] net/sched: act_tunnel_key: " Davide Caratti
2019-02-27 17:40 ` [PATCH net 16/16] net/sched: act_vlan: " Davide Caratti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=vbfimx2d02g.fsf@mellanox.com \
    --to=vladbu@mellanox.com \
    --cc=davem@davemloft.net \
    --cc=dcaratti@redhat.com \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=xiyou.wangcong@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.