From owner-svn-src-all@freebsd.org Thu Jun 18 20:49:57 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 97FF8333A1A; Thu, 18 Jun 2020 20:49:57 +0000 (UTC) (envelope-from kib@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 49nvFd3LFrz43Xk; Thu, 18 Jun 2020 20:49:57 +0000 (UTC) (envelope-from kib@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 69791FBB6; Thu, 18 Jun 2020 20:49:57 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05IKnvBK055273; Thu, 18 Jun 2020 20:49:57 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05IKnvje055272; Thu, 18 Jun 2020 20:49:57 GMT (envelope-from kib@FreeBSD.org) Message-Id: <202006182049.05IKnvje055272@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 18 Jun 2020 20:49:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r362342 - head/sys/compat/linux X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: head/sys/compat/linux X-SVN-Commit-Revision: 362342 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.33 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: Thu, 18 Jun 2020 20:49:57 -0000 Author: kib Date: Thu Jun 18 20:49:56 2020 New Revision: 362342 URL: https://svnweb.freebsd.org/changeset/base/362342 Log: Fix execution of linux binary from multithreaded non-Linux process. If multithreaded non-Linux process execs Linux binary, then non-Linux threads different from the one that execing are cleared by single-threading at boundary, and then terminating them in post_execve(). Since at that time the process is already switched to linux ABI, linuxolator is involved in the thread clearing on boundary, but cannot find the emul data. Handle it by pre-creating emuldata for all threads in the execing process. Also remove a code in linux_proc_exec() handler that cleared emul data for other threads when execing from multithreaded Linux process. It is excessive. PR: 247020 Reported by: Martin FIlla Reported by: Henrique L. Amorim, Independent Security Researcher Reported by: Rodrigo Rubira Branco (BSDaemon), Amazon Web Services Reviewed by: markj Tested by: trasz Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D25293 Modified: head/sys/compat/linux/linux_emul.c Modified: head/sys/compat/linux/linux_emul.c ============================================================================== --- head/sys/compat/linux/linux_emul.c Thu Jun 18 20:41:43 2020 (r362341) +++ head/sys/compat/linux/linux_emul.c Thu Jun 18 20:49:56 2020 (r362342) @@ -291,22 +291,13 @@ linux_common_execve(struct thread *td, struct image_ar void linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp) { - struct thread *td = curthread; + struct thread *td; struct thread *othertd; #if defined(__amd64__) struct linux_pemuldata *pem; #endif - /* - * In a case of execing from Linux binary properly detach - * other threads from the user space. - */ - if (__predict_false(SV_PROC_ABI(p) == SV_ABI_LINUX)) { - FOREACH_THREAD_IN_PROC(p, othertd) { - if (td != othertd) - (p->p_sysent->sv_thread_detach)(othertd); - } - } + td = curthread; /* * In a case of execing to Linux binary we create Linux @@ -314,11 +305,32 @@ linux_proc_exec(void *arg __unused, struct proc *p, st */ if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)) { - - if (SV_PROC_ABI(p) == SV_ABI_LINUX) + if (SV_PROC_ABI(p) == SV_ABI_LINUX) { + /* + * Process already was under Linuxolator + * before exec. Update emuldata to reflect + * single-threaded cleaned state after exec. + */ linux_proc_init(td, NULL, 0); - else + } else { + /* + * We are switching the process to Linux emulator. + */ linux_proc_init(td, td, 0); + + /* + * Create a transient td_emuldata for all suspended + * threads, so that p->p_sysent->sv_thread_detach() == + * linux_thread_detach() can find expected but unused + * emuldata. + */ + FOREACH_THREAD_IN_PROC(td->td_proc, othertd) { + if (othertd != td) { + linux_proc_init(td, othertd, + LINUX_CLONE_THREAD); + } + } + } #if defined(__amd64__) /* * An IA32 executable which has executable stack will have the