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 *);