Module Name:    src
Committed By:   martin
Date:           Sun Feb  4 11:20:15 UTC 2024

Modified Files:
        src/sys/kern [netbsd-10]: uipc_socket.c uipc_syscalls.c
        src/sys/net [netbsd-10]: if_gre.c
        src/sys/sys [netbsd-10]: socketvar.h

Log Message:
Pull up following revision(s) (requested by jdolecek in ticket #583):

        sys/kern/uipc_socket.c: revision 1.308
        sys/kern/uipc_syscalls.c: revision 1.211
        sys/sys/socketvar.h: revision 1.168
        sys/net/if_gre.c: revision 1.185

fix PIPE_SOCKETPAIR variant of pipe1() to apply correctly the 'flags'
passed when called via pipe2(2), fixing repeatable process hang during
compilation with 'gcc -pipe'

refactor fsocreate() to return the new socket and file pointers,
expect the caller to call fd_affix() once initialization is fully complete
use the new fsocreate() to replace the duplicate open-coded 'flags' handling
in makesocket() used for socketpair(2), and in the PIPE_SOCKETPAIR pipe1()
this also fixes lib/libc/sys/t_pipe2 pipe2_cloexec test to succeed
on PIPE_SOCKETPAIR kernel

fixes PR kern/55690


To generate a diff of this commit:
cvs rdiff -u -r1.302 -r1.302.4.1 src/sys/kern/uipc_socket.c
cvs rdiff -u -r1.206 -r1.206.4.1 src/sys/kern/uipc_syscalls.c
cvs rdiff -u -r1.184 -r1.184.4.1 src/sys/net/if_gre.c
cvs rdiff -u -r1.165 -r1.165.4.1 src/sys/sys/socketvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/uipc_socket.c
diff -u src/sys/kern/uipc_socket.c:1.302 src/sys/kern/uipc_socket.c:1.302.4.1
--- src/sys/kern/uipc_socket.c:1.302	Sat Apr  9 23:52:22 2022
+++ src/sys/kern/uipc_socket.c	Sun Feb  4 11:20:15 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_socket.c,v 1.302 2022/04/09 23:52:22 riastradh Exp $	*/
+/*	$NetBSD: uipc_socket.c,v 1.302.4.1 2024/02/04 11:20:15 martin Exp $	*/
 
 /*
  * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.302 2022/04/09 23:52:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.302.4.1 2024/02/04 11:20:15 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -568,44 +568,51 @@ socreate(int dom, struct socket **aso, i
 
 /*
  * fsocreate: create a socket and a file descriptor associated with it.
+ * Returns the allocated file structure in *fpp, but the descriptor
+ * is not visible yet for the process.
+ * Caller is responsible for calling fd_affix() for the returned *fpp once
+ * it's socket initialization is finished successfully, or fd_abort() if it's
+ * initialization fails.
+ * 
  *
- * => On success, write file descriptor to fdout and return zero.
- * => On failure, return non-zero; *fdout will be undefined.
+ * => On success, write file descriptor to *fdout and *fpp and return zero.
+ * => On failure, return non-zero; *fdout and *fpp will be undefined.
  */
 int
-fsocreate(int domain, struct socket **sop, int type, int proto, int *fdout)
+fsocreate(int domain, struct socket **sop, int type, int proto, int *fdout,
+    file_t **fpp, struct socket *lockso)
 {
 	lwp_t *l = curlwp;
 	int error, fd, flags;
 	struct socket *so;
-	struct file *fp;
+	file_t *fp;
+
+	flags = type & SOCK_FLAGS_MASK;
+	type &= ~SOCK_FLAGS_MASK;
+	error = socreate(domain, &so, type, proto, l, lockso);
+	if (error) {
+		return error;
+	}
 
 	if ((error = fd_allocfile(&fp, &fd)) != 0) {
+		soclose(so);
 		return error;
 	}
-	flags = type & SOCK_FLAGS_MASK;
 	fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0);
 	fp->f_flag = FREAD|FWRITE|((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)|
 	    ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0);
 	fp->f_type = DTYPE_SOCKET;
 	fp->f_ops = &socketops;
-
-	type &= ~SOCK_FLAGS_MASK;
-	error = socreate(domain, &so, type, proto, l, NULL);
-	if (error) {
-		fd_abort(curproc, fp, fd);
-		return error;
-	}
 	if (flags & SOCK_NONBLOCK) {
 		so->so_state |= SS_NBIO;
 	}
 	fp->f_socket = so;
-	fd_affix(curproc, fp, fd);
 
 	if (sop != NULL) {
 		*sop = so;
 	}
 	*fdout = fd;
+	*fpp = fp;
 	return error;
 }
 

Index: src/sys/kern/uipc_syscalls.c
diff -u src/sys/kern/uipc_syscalls.c:1.206 src/sys/kern/uipc_syscalls.c:1.206.4.1
--- src/sys/kern/uipc_syscalls.c:1.206	Fri Jul  1 22:30:51 2022
+++ src/sys/kern/uipc_syscalls.c	Sun Feb  4 11:20:15 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_syscalls.c,v 1.206 2022/07/01 22:30:51 riastradh Exp $	*/
+/*	$NetBSD: uipc_syscalls.c,v 1.206.4.1 2024/02/04 11:20:15 martin Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.206 2022/07/01 22:30:51 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.206.4.1 2024/02/04 11:20:15 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pipe.h"
@@ -111,10 +111,12 @@ sys___socket30(struct lwp *l, const stru
 		syscallarg(int)	protocol;
 	} */
 	int fd, error;
+	file_t *fp;
 
 	error = fsocreate(SCARG(uap, domain), NULL, SCARG(uap, type),
-	    SCARG(uap, protocol), &fd);
+	    SCARG(uap, protocol), &fd, &fp, NULL);
 	if (error == 0) {
+		fd_affix(l->l_proc, fp, fd);
 		*retval = fd;
 	}
 	return error;
@@ -402,34 +404,6 @@ do_sys_connect(struct lwp *l, int fd, st
 	return error;
 }
 
-static int
-makesocket(struct lwp *l, file_t **fp, int *fd, int flags, int type,
-    int domain, int proto, struct socket *soo)
-{
-	struct socket *so;
-	int error;
-
-	if ((error = socreate(domain, &so, type, proto, l, soo)) != 0) {
-		return error;
-	}
-	if (flags & SOCK_NONBLOCK) {
-		so->so_state |= SS_NBIO;
-	}
-
-	if ((error = fd_allocfile(fp, fd)) != 0) {
-		soclose(so);
-		return error;
-	}
-	fd_set_exclose(l, *fd, (flags & SOCK_CLOEXEC) != 0);
-	(*fp)->f_flag = FREAD|FWRITE|
-	    ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)|
-	    ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0);
-	(*fp)->f_type = DTYPE_SOCKET;
-	(*fp)->f_ops = &socketops;
-	(*fp)->f_socket = so;
-	return 0;
-}
-
 int
 sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap,
     register_t *retval)
@@ -449,16 +423,14 @@ sys_socketpair(struct lwp *l, const stru
 	int		domain = SCARG(uap, domain);
 	int		proto = SCARG(uap, protocol);
 
-	error = makesocket(l, &fp1, &fd, flags, type, domain, proto, NULL);
+	error = fsocreate(domain, &so1, type|flags, proto, &fd, &fp1, NULL);
 	if (error)
 		return error;
-	so1 = fp1->f_socket;
 	sv[0] = fd;
 
-	error = makesocket(l, &fp2, &fd, flags, type, domain, proto, so1);
+	error = fsocreate(domain, &so2, type|flags, proto, &fd, &fp2, so1);
 	if (error)
 		goto out;
-	so2 = fp2->f_socket;
 	sv[1] = fd;
 
 	solock(so1);
@@ -1297,33 +1269,36 @@ pipe1(struct lwp *l, int *fildes, int fl
 {
 	file_t		*rf, *wf;
 	struct socket	*rso, *wso;
-	int		fd, error;
-	proc_t		*p;
+	int		error, soflags = 0;
+	unsigned	rfd, wfd;
+	proc_t		*p = l->l_proc;
 
 	if (flags & ~(O_CLOEXEC|O_NONBLOCK|O_NOSIGPIPE))
 		return EINVAL;
-	p = curproc;
-	if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL)) != 0)
-		return error;
-	if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l, rso)) != 0)
+	if (flags & O_CLOEXEC)
+		soflags |= SOCK_CLOEXEC;
+	if (flags & O_NONBLOCK)
+		soflags |= SOCK_NONBLOCK;
+	if (flags & O_NOSIGPIPE)
+		soflags |= SOCK_NOSIGPIPE;
+
+	error = fsocreate(AF_LOCAL, &rso, SOCK_STREAM|soflags, 0, &rfd, &rf,
+	    NULL);
+	if (error)
 		goto free1;
+	error = fsocreate(AF_LOCAL, &wso, SOCK_STREAM|soflags, 0, &wfd, &wf,
+	    rso);
+	if (error)
+		goto free2;
+
+	/* make sure the descriptors are uni-directional */
+	rf->f_type = rf->f_type & ~(FWRITE);
+	wf->f_type = wf->f_type & ~(FREAD);
+
 	/* remember this socket pair implements a pipe */
-	wso->so_state |= SS_ISAPIPE;
 	rso->so_state |= SS_ISAPIPE;
-	if ((error = fd_allocfile(&rf, &fd)) != 0)
-		goto free2;
-	fildes[0] = fd;
-	rf->f_flag = FREAD | flags;
-	rf->f_type = DTYPE_SOCKET;
-	rf->f_ops = &socketops;
-	rf->f_socket = rso;
-	if ((error = fd_allocfile(&wf, &fd)) != 0)
-		goto free3;
-	wf->f_flag = FWRITE | flags;
-	wf->f_type = DTYPE_SOCKET;
-	wf->f_ops = &socketops;
-	wf->f_socket = wso;
-	fildes[1] = fd;
+	wso->so_state |= SS_ISAPIPE;
+
 	solock(wso);
 	/*
 	 * Pipes must be readable when there is at least 1
@@ -1342,19 +1317,22 @@ pipe1(struct lwp *l, int *fildes, int fl
 	wso->so_snd.sb_lowat = PIPE_BUF;
 	error = unp_connect2(wso, rso);
 	sounlock(wso);
+
 	if (error != 0)
-		goto free4;
-	fd_affix(p, wf, fildes[1]);
-	fd_affix(p, rf, fildes[0]);
+		goto free3;
+
+	fd_affix(p, wf, wfd);
+	fd_affix(p, rf, rfd);
+	fildes[0] = rfd;
+	fildes[1] = wfd;
 	return (0);
- free4:
-	fd_abort(p, wf, fildes[1]);
  free3:
-	fd_abort(p, rf, fildes[0]);
- free2:
 	(void)soclose(wso);
- free1:
+	fd_abort(p, wf, wfd);
+ free2:
 	(void)soclose(rso);
+	fd_abort(p, rf, rfd);
+ free1:
 	return error;
 }
 #endif /* PIPE_SOCKETPAIR */

Index: src/sys/net/if_gre.c
diff -u src/sys/net/if_gre.c:1.184 src/sys/net/if_gre.c:1.184.4.1
--- src/sys/net/if_gre.c:1.184	Sat Sep  3 02:47:59 2022
+++ src/sys/net/if_gre.c	Sun Feb  4 11:20:15 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_gre.c,v 1.184 2022/09/03 02:47:59 thorpej Exp $ */
+/*	$NetBSD: if_gre.c,v 1.184.4.1 2024/02/04 11:20:15 martin Exp $ */
 
 /*
  * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.184 2022/09/03 02:47:59 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.184.4.1 2024/02/04 11:20:15 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_atalk.h"
@@ -435,6 +435,7 @@ static int
 gre_socreate(struct gre_softc *sc, const struct gre_soparm *sp, int *fdout)
 {
 	int fd, rc;
+	file_t *fp;
 	struct socket *so;
 	struct sockaddr_big sbig;
 	sa_family_t af;
@@ -443,15 +444,12 @@ gre_socreate(struct gre_softc *sc, const
 	GRE_DPRINTF(sc, "enter\n");
 
 	af = sp->sp_src.ss_family;
-	rc = fsocreate(af, NULL, sp->sp_type, sp->sp_proto, &fd);
+	rc = fsocreate(af, &so, sp->sp_type, sp->sp_proto, &fd, &fp, NULL);
 	if (rc != 0) {
 		GRE_DPRINTF(sc, "fsocreate failed\n");
 		return rc;
 	}
 
-	if ((rc = fd_getsock(fd, &so)) != 0)
-		return rc;
-
 	memcpy(&sbig, &sp->sp_src, sizeof(sp->sp_src));
 	if ((rc = sobind(so, (struct sockaddr *)&sbig, curlwp)) != 0) {
 		GRE_DPRINTF(sc, "sobind failed\n");
@@ -484,10 +482,11 @@ gre_socreate(struct gre_softc *sc, const
 		rc = 0;
 	}
 out:
-	if (rc != 0)
-		fd_close(fd);
-	else  {
-		fd_putfile(fd);
+	if (rc != 0) {
+		soclose(so);
+		fd_abort(curproc, fp, fd);
+	} else  {
+		fd_affix(curproc, fp, fd);
 		*fdout = fd;
 	}
 

Index: src/sys/sys/socketvar.h
diff -u src/sys/sys/socketvar.h:1.165 src/sys/sys/socketvar.h:1.165.4.1
--- src/sys/sys/socketvar.h:1.165	Sat Apr  9 23:52:23 2022
+++ src/sys/sys/socketvar.h	Sun Feb  4 11:20:15 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: socketvar.h,v 1.165 2022/04/09 23:52:23 riastradh Exp $	*/
+/*	$NetBSD: socketvar.h,v 1.165.4.1 2024/02/04 11:20:15 martin Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -306,7 +306,8 @@ int	soconnect(struct socket *, struct so
 int	soconnect2(struct socket *, struct socket *);
 int	socreate(int, struct socket **, int, int, struct lwp *,
 		 struct socket *);
-int	fsocreate(int, struct socket **, int, int, int *);
+int	fsocreate(int, struct socket **, int, int, int *, file_t **,
+		struct socket *);
 int	sodisconnect(struct socket *);
 void	sofree(struct socket *);
 int	sogetopt(struct socket *, struct sockopt *);

Reply via email to