From: Simon Horman <horms@kernel.org>
To: Stefan Wiehler <stefan.wiehler@nokia.com>
Cc: "David S . Miller" <davem@davemloft.net>,
David Ahern <dsahern@kernel.org>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net v3 3/4] ip6mr: Lock RCU before ip6mr_get_table() call in ip6mr_compat_ioctl()
Date: Thu, 10 Oct 2024 10:41:30 +0100 [thread overview]
Message-ID: <20241010094130.GA1098236@kernel.org> (raw)
In-Reply-To: <20241010090741.1980100-7-stefan.wiehler@nokia.com>
On Thu, Oct 10, 2024 at 11:07:44AM +0200, Stefan Wiehler wrote:
> When IPV6_MROUTE_MULTIPLE_TABLES is enabled, calls to ip6mr_get_table()
> must be done under RCU or RTNL lock. Copy from user space must be
> performed beforehand as we are not allowed to sleep under RCU lock.
>
> Signed-off-by: Stefan Wiehler <stefan.wiehler@nokia.com>
> Fixes: d1db275dd3f6 ("ipv6: ip6mr: support multiple tables")
> ---
> v3:
> - split into separate patches
> v2: https://patchwork.kernel.org/project/netdevbpf/patch/20241001100119.230711-2-stefan.wiehler@nokia.com/
> - rebase on top of net tree
> - add Fixes tag
> - refactor out paths
> v1: https://patchwork.kernel.org/project/netdevbpf/patch/20240605195355.363936-1-oss@malat.biz/
> ---
> net/ipv6/ip6mr.c | 46 ++++++++++++++++++++++++++++++++--------------
> 1 file changed, 32 insertions(+), 14 deletions(-)
>
> diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
> index b18eb4ad21e4..415ba6f55a44 100644
> --- a/net/ipv6/ip6mr.c
> +++ b/net/ipv6/ip6mr.c
> @@ -1961,10 +1961,7 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
> struct mfc6_cache *c;
> struct net *net = sock_net(sk);
> struct mr_table *mrt;
> -
> - mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
> - if (!mrt)
> - return -ENOENT;
> + int err;
>
> switch (cmd) {
> case SIOCGETMIFCNT_IN6:
> @@ -1972,8 +1969,30 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
> return -EFAULT;
> if (vr.mifi >= mrt->maxvif)
> return -EINVAL;
Hi Stefan,
mrt is now used uninitialised here.
> + break;
> + case SIOCGETSGCNT_IN6:
> + if (copy_from_user(&sr, arg, sizeof(sr)))
> + return -EFAULT;
> + break;
> + default:
> + return -ENOIOCTLCMD;
> + }
> +
> +
> + rcu_read_lock();
> + mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
> + if (!mrt) {
> + err = -ENOENT;
> + goto out;
> + }
> +
> + switch (cmd) {
> + case SIOCGETMIFCNT_IN6:
> + if (vr.mifi >= mrt->maxvif) {
> + err = -EINVAL;
> + goto out;
> + }
> vr.mifi = array_index_nospec(vr.mifi, mrt->maxvif);
> - rcu_read_lock();
> vif = &mrt->vif_table[vr.mifi];
> if (VIF_EXISTS(mrt, vr.mifi)) {
> vr.icount = READ_ONCE(vif->pkt_in);
...
> @@ -2004,11 +2020,13 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
> return -EFAULT;
> return 0;
> }
> - rcu_read_unlock();
> - return -EADDRNOTAVAIL;
> - default:
> - return -ENOIOCTLCMD;
> + err = -EADDRNOTAVAIL;
> + goto out;
> }
> +
I think that this out label should be used consistently once rcu_read_lock
has been taken. With this patch applied there seems to be one case on error
where rcu_read_unlock() before returning, and one case where it isn't
(which looks like it leaks the lock).
> +out:
> + rcu_read_unlock();
> + return err;
> }
> #endif
--
pw-bot: changes-requested
next prev parent reply other threads:[~2024-10-10 9:41 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-10 9:07 [PATCH net v3 1/4] ip6mr: Lock RCU before ip6mr_get_table() call in ip6mr_vif_seq_start() Stefan Wiehler
2024-10-10 9:07 ` [PATCH net v3 2/4] ip6mr: Lock RCU before ip6mr_get_table() call in ip6mr_ioctl() Stefan Wiehler
2024-10-10 9:07 ` [PATCH net v3 3/4] ip6mr: Lock RCU before ip6mr_get_table() call in ip6mr_compat_ioctl() Stefan Wiehler
2024-10-10 9:41 ` Simon Horman [this message]
2024-10-10 14:43 ` Stefan Wiehler
2024-10-11 10:16 ` Simon Horman
2024-10-14 15:05 ` Stefan Wiehler
2024-10-11 17:11 ` kernel test robot
2024-10-10 9:07 ` [PATCH net v3 4/4] ip6mr: Lock RCU before ip6mr_get_table() call in ip6mr_get_route() Stefan Wiehler
2024-10-10 9:33 ` Eric Dumazet
2024-10-10 9:44 ` [PATCH net v3 1/4] ip6mr: Lock RCU before ip6mr_get_table() call in ip6mr_vif_seq_start() Eric Dumazet
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=20241010094130.GA1098236@kernel.org \
--to=horms@kernel.org \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stefan.wiehler@nokia.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.