[PATCH net] l2tp: send netlink notifications in the tunnel's net namespace

Maoyi Xie <[email protected]>
Newsgroups gmane.linux.network,gmane.linux.kernel,gmane.linux.kernel.stable
Message-ID <[email protected]>
l2tp_tunnel_notify() and l2tp_session_notify() use
genlmsg_multicast_allns(), which delivers to listeners in every network
namespace. l2tp is per-namespace, and a tunnel records the namespace it
belongs to in tunnel->l2tp_net. Each event concerns one namespace, yet
every namespace is told about it. A tunnel event carries the tunnel and
peer tunnel ids, plus the socket's addresses with both ports for a UDP
tunnel. A session event carries the session and peer session ids, the
interface name, plus the L2TP cookies where those are set. A listener
needs no privilege for any of this, because l2tp_multicast_group[]
carries no flags and genl_bind() asks for no capability.

The fix is to send to the tunnel's namespace with
genlmsg_multicast_netns(). Commit 134e63756d5f ("genetlink: make netns
aware") added both helpers and drew the line between them. The netns
variant is for an object that lives in a namespace.

I found this by auditing the tree's six genlmsg_multicast_allns() call
sites for objects that live in a network namespace. Only the two l2tp
ones do.

I reproduced it on net at dd057113ac7b, in a virtual machine, with no
real hardware involved. A process in the initial namespace, running as
an ordinary user with an empty capability set, receives the create and
delete events of a tunnel. The tunnel was set up inside an unprivileged
user and network namespace. tools/testing/selftests/net/l2tp.sh passes
before and after.

On a container host, any local user and every other tenant can read a
tenant's tunnel parameters.

Fixes: 33f72e6f0c67 ("l2tp : multicast notification to the registered listeners")
Cc: [email protected]
Signed-off-by: Maoyi Xie <[email protected]>
---
 net/l2tp/l2tp_netlink.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 59457c0c14aab..c0c4d1ebc7a3e 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -116,7 +116,8 @@ static int l2tp_tunnel_notify(struct genl_family *family,
 				  NLM_F_ACK, tunnel, cmd);
 
 	if (ret >= 0) {
-		ret = genlmsg_multicast_allns(family, msg, 0, 0);
+		ret = genlmsg_multicast_netns(family, tunnel->l2tp_net, msg,
+					      0, 0, GFP_KERNEL);
 		/* We don't care if no one is listening */
 		if (ret == -ESRCH)
 			ret = 0;
@@ -144,7 +145,9 @@ static int l2tp_session_notify(struct genl_family *family,
 				   NLM_F_ACK, session, cmd);
 
 	if (ret >= 0) {
-		ret = genlmsg_multicast_allns(family, msg, 0, 0);
+		ret = genlmsg_multicast_netns(family,
+					      session->tunnel->l2tp_net, msg,
+					      0, 0, GFP_KERNEL);
 		/* We don't care if no one is listening */
 		if (ret == -ESRCH)
 			ret = 0;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.