From owner-svn-src-all@freebsd.org Tue Nov 17 21:20:12 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id B2FDE46F9AE; Tue, 17 Nov 2020 21:20:12 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CbJkN4l7wz3hk6; Tue, 17 Nov 2020 21:20:12 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 956D32693E; Tue, 17 Nov 2020 21:20:12 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0AHLKCDB068443; Tue, 17 Nov 2020 21:20:12 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0AHLKBQv068440; Tue, 17 Nov 2020 21:20:11 GMT (envelope-from cem@FreeBSD.org) Message-Id: <202011172120.0AHLKBQv068440@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer Date: Tue, 17 Nov 2020 21:20:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r367778 - in head/sys: compat/linux kern sys X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: in head/sys: compat/linux kern sys X-SVN-Commit-Revision: 367778 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Nov 2020 21:20:12 -0000 Author: cem Date: Tue Nov 17 21:20:11 2020 New Revision: 367778 URL: https://svnweb.freebsd.org/changeset/base/367778 Log: linux(4) clone(2): Correctly handle CLONE_FS and CLONE_FILES The two flags are distinct and it is impossible to correctly handle clone(2) without the assistance of fork1(). This change depends on the pwddesc split introduced in r367777. I've added a fork_req flag, FR2_SHARE_PATHS, which indicates that p_pd should be treated the opposite way p_fd is (based on RFFDG flag). This is a little ugly, but the benefit is that existing RFFDG API is preserved. Holding FR2_SHARE_PATHS disabled, RFFDG indicates both p_fd and p_pd are copied, while !RFFDG indicates both should be cloned. In Chrome, clone(2) is used with CLONE_FS, without CLONE_FILES, and expects independent fd tables. The previous conflation of CLONE_FS and CLONE_FILES was introduced in r163371 (2006). Discussed with: markj, trasz (earlier version) Differential Revision: https://reviews.freebsd.org/D27016 Modified: head/sys/compat/linux/linux_fork.c head/sys/kern/kern_fork.c head/sys/sys/proc.h Modified: head/sys/compat/linux/linux_fork.c ============================================================================== --- head/sys/compat/linux/linux_fork.c Tue Nov 17 21:14:13 2020 (r367777) +++ head/sys/compat/linux/linux_fork.c Tue Nov 17 21:20:11 2020 (r367778) @@ -131,12 +131,13 @@ static int linux_clone_proc(struct thread *td, struct linux_clone_args *args) { struct fork_req fr; - int error, ff = RFPROC | RFSTOPPED; + int error, ff = RFPROC | RFSTOPPED, f2; struct proc *p2; struct thread *td2; int exit_signal; struct linux_emuldata *em; + f2 = 0; exit_signal = args->flags & 0x000000ff; if (LINUX_SIG_VALID(exit_signal)) { exit_signal = linux_to_bsd_signal(exit_signal); @@ -147,14 +148,14 @@ linux_clone_proc(struct thread *td, struct linux_clone ff |= RFMEM; if (args->flags & LINUX_CLONE_SIGHAND) ff |= RFSIGSHARE; - /* - * XXX: In Linux, sharing of fs info (chroot/cwd/umask) - * and open files is independent. In FreeBSD, its in one - * structure but in reality it does not cause any problems - * because both of these flags are usually set together. - */ - if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS))) + if (args->flags & LINUX_CLONE_FILES) { + if (!(args->flags & LINUX_CLONE_FS)) + f2 |= FR2_SHARE_PATHS; + } else { ff |= RFFDG; + if (args->flags & LINUX_CLONE_FS) + f2 |= FR2_SHARE_PATHS; + } if (args->flags & LINUX_CLONE_PARENT_SETTID) if (args->parent_tidptr == NULL) @@ -165,6 +166,7 @@ linux_clone_proc(struct thread *td, struct linux_clone bzero(&fr, sizeof(fr)); fr.fr_flags = ff; + fr.fr_flags2 = f2; fr.fr_procp = &p2; error = fork1(td, &fr); if (error) Modified: head/sys/kern/kern_fork.c ============================================================================== --- head/sys/kern/kern_fork.c Tue Nov 17 21:14:13 2020 (r367777) +++ head/sys/kern/kern_fork.c Tue Nov 17 21:20:11 2020 (r367778) @@ -414,11 +414,17 @@ do_fork(struct thread *td, struct fork_req *fr, struct fd = fdinit(p1->p_fd, false, NULL); fdtol = NULL; } else if (fr->fr_flags & RFFDG) { - pd = pdcopy(p1->p_pd); + if (fr->fr_flags2 & FR2_SHARE_PATHS) + pd = pdshare(p1->p_pd); + else + pd = pdcopy(p1->p_pd); fd = fdcopy(p1->p_fd); fdtol = NULL; } else { - pd = pdshare(p1->p_pd); + if (fr->fr_flags2 & FR2_SHARE_PATHS) + pd = pdcopy(p1->p_pd); + else + pd = pdshare(p1->p_pd); fd = fdshare(p1->p_fd); if (p1->p_fdtol == NULL) p1->p_fdtol = filedesc_to_leader_alloc(NULL, NULL, Modified: head/sys/sys/proc.h ============================================================================== --- head/sys/sys/proc.h Tue Nov 17 21:14:13 2020 (r367777) +++ head/sys/sys/proc.h Tue Nov 17 21:20:11 2020 (r367778) @@ -1017,7 +1017,8 @@ struct fork_req { int fr_pd_flags; struct filecaps *fr_pd_fcaps; int fr_flags2; -#define FR2_DROPSIG_CAUGHT 0x00001 /* Drop caught non-DFL signals */ +#define FR2_DROPSIG_CAUGHT 0x00000001 /* Drop caught non-DFL signals */ +#define FR2_SHARE_PATHS 0x00000002 /* Invert sense of RFFDG for paths */ }; /*