lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241210073829.62520-8-kuniyu@amazon.com>
Date: Tue, 10 Dec 2024 16:38:21 +0900
From: Kuniyuki Iwashima <kuniyu@...zon.com>
To: "David S. Miller" <davem@...emloft.net>, Eric Dumazet
	<edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>, Paolo Abeni
	<pabeni@...hat.com>, Simon Horman <horms@...nel.org>
CC: Kuniyuki Iwashima <kuniyu@...zon.com>, Kuniyuki Iwashima
	<kuni1840@...il.com>, <netdev@...r.kernel.org>
Subject: [PATCH v2 net-next 07/15] socket: Add hold_net flag to struct proto_accept_arg.

We will introduce a new API to create a kernel socket with netns refcnt
held.  Then, sk_alloc() need the hold_net flag passed from the accept()
paths.

Let's add a new hold_net flag to struct proto_accept_arg and pass it
down before sk_alloc().

Signed-off-by: Kuniyuki Iwashima <kuniyu@...zon.com>
---
 drivers/xen/pvcalls-back.c | 1 +
 fs/ocfs2/cluster/tcp.c     | 2 ++
 include/net/sctp/structs.h | 2 +-
 include/net/sock.h         | 1 +
 io_uring/net.c             | 2 ++
 net/atm/svc.c              | 2 +-
 net/rds/tcp_listen.c       | 1 +
 net/sctp/ipv6.c            | 7 ++++---
 net/sctp/protocol.c        | 7 ++++---
 net/sctp/socket.c          | 2 +-
 net/socket.c               | 6 +++++-
 net/tipc/socket.c          | 2 +-
 12 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c
index fd7ed65e0197..f0f8b4862983 100644
--- a/drivers/xen/pvcalls-back.c
+++ b/drivers/xen/pvcalls-back.c
@@ -520,6 +520,7 @@ static void __pvcalls_back_accept(struct work_struct *work)
 	struct proto_accept_arg arg = {
 		.flags = O_NONBLOCK,
 		.kern = true,
+		.hold_net = false,
 	};
 	struct sock_mapping *map;
 	struct pvcalls_ioworker *iow;
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 2b8fa3e782fb..6ef03a02d19b 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -1786,6 +1786,8 @@ static int o2net_accept_one(struct socket *sock, int *more)
 	struct o2net_sock_container *sc = NULL;
 	struct proto_accept_arg arg = {
 		.flags = O_NONBLOCK,
+		.kern = false,
+		.hold_net = true,
 	};
 	struct o2net_node *nn;
 	unsigned int nofs_flag;
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 31248cfdfb23..ae2729ab2040 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -502,7 +502,7 @@ struct sctp_pf {
 	int  (*supported_addrs)(const struct sctp_sock *, __be16 *);
 	struct sock *(*create_accept_sk) (struct sock *sk,
 					  struct sctp_association *asoc,
-					  bool kern);
+					  struct proto_accept_arg *arg);
 	int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
 	void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
 	void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
diff --git a/include/net/sock.h b/include/net/sock.h
index 7464e9f9f47c..9963dccec2f8 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1214,6 +1214,7 @@ struct proto_accept_arg {
 	int err;
 	int is_empty;
 	bool kern;
+	bool hold_net;
 };
 
 /* Networking protocol blocks we attach to sockets.
diff --git a/io_uring/net.c b/io_uring/net.c
index df1f7dc6f1c8..93418208b37d 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -1559,6 +1559,8 @@ int io_accept(struct io_kiocb *req, unsigned int issue_flags)
 	bool fixed = !!accept->file_slot;
 	struct proto_accept_arg arg = {
 		.flags = force_nonblock ? O_NONBLOCK : 0,
+		.kern = false,
+		.hold_net = true,
 	};
 	struct file *file;
 	unsigned cflags;
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 9795294f4c1e..a23699acb3fd 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -336,7 +336,7 @@ static int svc_accept(struct socket *sock, struct socket *newsock,
 
 	lock_sock(sk);
 
-	error = svc_create(sock_net(sk), newsock, 0, arg->kern, !arg->kern);
+	error = svc_create(sock_net(sk), newsock, 0, arg->kern, arg->hold_net);
 	if (error)
 		goto out;
 
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index d89bd8d0c354..69aaf03ab93e 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -108,6 +108,7 @@ int rds_tcp_accept_one(struct socket *sock)
 	struct proto_accept_arg arg = {
 		.flags = O_NONBLOCK,
 		.kern = true,
+		.hold_net = false,
 	};
 #if !IS_ENABLED(CONFIG_IPV6)
 	struct in6_addr saddr, daddr;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index a9ed2ccab1bd..2c4e4dd79246 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -777,13 +777,14 @@ static enum sctp_scope sctp_v6_scope(union sctp_addr *addr)
 /* Create and initialize a new sk for the socket to be returned by accept(). */
 static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
 					     struct sctp_association *asoc,
-					     bool kern)
+					     struct proto_accept_arg *arg)
 {
-	struct sock *newsk;
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct sctp6_sock *newsctp6sk;
+	struct sock *newsk;
 
-	newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, kern);
+	newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot,
+			 arg->kern);
 	if (!newsk)
 		goto out;
 
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 8b9a1b96695e..7b2ae3df171a 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -581,12 +581,13 @@ static int sctp_v4_is_ce(const struct sk_buff *skb)
 /* Create and initialize a new sk for the socket returned by accept(). */
 static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
 					     struct sctp_association *asoc,
-					     bool kern)
+					     struct proto_accept_arg *arg)
 {
-	struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL,
-			sk->sk_prot, kern);
 	struct inet_sock *newinet;
+	struct sock *newsk;
 
+	newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL, sk->sk_prot,
+			 arg->kern);
 	if (!newsk)
 		goto out;
 
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 36ee34f483d7..a1add0b7fd9f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4887,7 +4887,7 @@ static struct sock *sctp_accept(struct sock *sk, struct proto_accept_arg *arg)
 	 */
 	asoc = list_entry(ep->asocs.next, struct sctp_association, asocs);
 
-	newsk = sp->pf->create_accept_sk(sk, asoc, arg->kern);
+	newsk = sp->pf->create_accept_sk(sk, asoc, arg);
 	if (!newsk) {
 		error = -ENOMEM;
 		goto out;
diff --git a/net/socket.c b/net/socket.c
index d1b4dadd67e4..a8796d7f06be 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1971,7 +1971,10 @@ struct file *do_accept(struct file *file, struct proto_accept_arg *arg,
 static int __sys_accept4_file(struct file *file, struct sockaddr __user *upeer_sockaddr,
 			      int __user *upeer_addrlen, int flags)
 {
-	struct proto_accept_arg arg = { };
+	struct proto_accept_arg arg = {
+		.kern = false,
+		.hold_net = true,
+	};
 	struct file *newfile;
 	int newfd;
 
@@ -3586,6 +3589,7 @@ int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
 	struct proto_accept_arg arg = {
 		.flags = flags,
 		.kern = true,
+		.hold_net = false,
 	};
 	int err;
 
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 4ee0bd1043e1..26566ff1d4c7 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2737,7 +2737,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock,
 	buf = skb_peek(&sk->sk_receive_queue);
 
 	res = tipc_sk_create(sock_net(sock->sk), new_sock, 0,
-			     arg->kern, !arg->kern);
+			     arg->kern, arg->hold_net);
 	if (res)
 		goto exit;
 	security_sk_clone(sock->sk, new_sock->sk);
-- 
2.39.5 (Apple Git-154)


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ