From owner-svn-src-all@freebsd.org Sun May 19 12:58:46 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 58A9815AD4E6; Sun, 19 May 2019 12:58:46 +0000 (UTC) (envelope-from trasz@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) server-signature RSA-PSS (4096 bits) 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 ECEAB8B839; Sun, 19 May 2019 12:58:45 +0000 (UTC) (envelope-from trasz@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 C0D9774EC; Sun, 19 May 2019 12:58:45 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x4JCwjRx050473; Sun, 19 May 2019 12:58:45 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4JCwjWS050469; Sun, 19 May 2019 12:58:45 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201905191258.x4JCwjWS050469@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Sun, 19 May 2019 12:58:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r347971 - in head/sys: amd64/linux compat/linux X-SVN-Group: head X-SVN-Commit-Author: trasz X-SVN-Commit-Paths: in head/sys: amd64/linux compat/linux X-SVN-Commit-Revision: 347971 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: ECEAB8B839 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.97)[-0.971,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 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: Sun, 19 May 2019 12:58:46 -0000 Author: trasz Date: Sun May 19 12:58:44 2019 New Revision: 347971 URL: https://svnweb.freebsd.org/changeset/base/347971 Log: Implement PTRACE_O_TRACESYSGOOD. This makes Linux strace(1) work. Reviewed by: dchagin MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D20200 Modified: head/sys/amd64/linux/linux_ptrace.c head/sys/compat/linux/linux_emul.h head/sys/compat/linux/linux_misc.c head/sys/compat/linux/linux_misc.h Modified: head/sys/amd64/linux/linux_ptrace.c ============================================================================== --- head/sys/amd64/linux/linux_ptrace.c Sun May 19 09:24:51 2019 (r347970) +++ head/sys/amd64/linux/linux_ptrace.c Sun May 19 12:58:44 2019 (r347971) @@ -34,8 +34,10 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include +#include #include #include @@ -43,6 +45,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #define LINUX_PTRACE_TRACEME 0 @@ -107,6 +111,37 @@ map_signum(int lsig, int *bsigp) return (0); } +int +linux_ptrace_status(struct thread *td, pid_t pid, int status) +{ + struct ptrace_lwpinfo lwpinfo; + struct linux_pemuldata *pem; + register_t saved_retval; + int error; + + saved_retval = td->td_retval[0]; + error = kern_ptrace(td, PT_LWPINFO, pid, &lwpinfo, sizeof(lwpinfo)); + td->td_retval[0] = saved_retval; + if (error != 0) { + printf("%s: PT_LWPINFO failed with error %d\n", __func__, error); + return (status); + } + + pem = pem_find(td->td_proc); + KASSERT(pem != NULL, ("%s: proc emuldata not found.\n", __func__)); + + LINUX_PEM_SLOCK(pem); + if ((pem->ptrace_flags & LINUX_PTRACE_O_TRACESYSGOOD) && + lwpinfo.pl_flags & PL_FLAG_SCE) + status |= (LINUX_SIGTRAP | 0x80) << 8; + if ((pem->ptrace_flags & LINUX_PTRACE_O_TRACESYSGOOD) && + lwpinfo.pl_flags & PL_FLAG_SCX) + status |= (LINUX_SIGTRAP | 0x80) << 8; + LINUX_PEM_SUNLOCK(pem); + + return (status); +} + struct linux_pt_reg { l_ulong r15; l_ulong r14; @@ -279,6 +314,7 @@ linux_ptrace_peek(struct thread *td, pid_t pid, void * static int linux_ptrace_setoptions(struct thread *td, pid_t pid, l_ulong data) { + struct linux_pemuldata *pem; int mask; mask = 0; @@ -290,15 +326,20 @@ linux_ptrace_setoptions(struct thread *td, pid_t pid, return (EINVAL); } + pem = pem_find(td->td_proc); + KASSERT(pem != NULL, ("%s: proc emuldata not found.\n", __func__)); + /* * PTRACE_O_EXITKILL is ignored, we do that by default. */ + LINUX_PEM_XLOCK(pem); if (data & LINUX_PTRACE_O_TRACESYSGOOD) { - printf("%s: PTRACE_O_TRACESYSGOOD not implemented; " - "returning EINVAL\n", __func__); - return (EINVAL); + pem->ptrace_flags |= LINUX_PTRACE_O_TRACESYSGOOD; + } else { + pem->ptrace_flags &= ~LINUX_PTRACE_O_TRACESYSGOOD; } + LINUX_PEM_XUNLOCK(pem); if (data & LINUX_PTRACE_O_TRACEFORK) mask |= PTRACE_FORK; Modified: head/sys/compat/linux/linux_emul.h ============================================================================== --- head/sys/compat/linux/linux_emul.h Sun May 19 09:24:51 2019 (r347970) +++ head/sys/compat/linux/linux_emul.h Sun May 19 12:58:44 2019 (r347971) @@ -32,6 +32,8 @@ #ifndef _LINUX_EMUL_H_ #define _LINUX_EMUL_H_ +struct image_params; + /* * modeled after similar structure in NetBSD * this will be extended as we need more functionality @@ -68,6 +70,7 @@ struct linux_pemuldata { struct sx pem_sx; /* lock for this struct */ void *epoll; /* epoll data */ uint32_t persona; /* process execution domain */ + uint32_t ptrace_flags; /* used by ptrace(2) */ }; #define LINUX_PEM_XLOCK(p) sx_xlock(&(p)->pem_sx) Modified: head/sys/compat/linux/linux_misc.c ============================================================================== --- head/sys/compat/linux/linux_misc.c Sun May 19 09:24:51 2019 (r347970) +++ head/sys/compat/linux/linux_misc.c Sun May 19 12:58:44 2019 (r347971) @@ -886,27 +886,53 @@ linux_futimesat(struct thread *td, struct linux_futime } #endif -int -linux_common_wait(struct thread *td, int pid, int *status, - int options, struct rusage *ru) +static int +linux_common_wait(struct thread *td, int pid, int *statusp, + int options, struct __wrusage *wrup) { - int error, tmpstat; + siginfo_t siginfo; + idtype_t idtype; + id_t id; + int error, status, tmpstat; - error = kern_wait(td, pid, &tmpstat, options, ru); + if (pid == WAIT_ANY) { + idtype = P_ALL; + id = 0; + } else if (pid < 0) { + idtype = P_PGID; + id = (id_t)-pid; + } else { + idtype = P_PID; + id = (id_t)pid; + } + + /* + * For backward compatibility we implicitly add flags WEXITED + * and WTRAPPED here. + */ + options |= WEXITED | WTRAPPED; + error = kern_wait6(td, idtype, id, &status, options, wrup, &siginfo); if (error) return (error); - if (status) { - tmpstat &= 0xffff; - if (WIFSIGNALED(tmpstat)) + if (statusp) { + tmpstat = status & 0xffff; + if (WIFSIGNALED(tmpstat)) { tmpstat = (tmpstat & 0xffffff80) | bsd_to_linux_signal(WTERMSIG(tmpstat)); - else if (WIFSTOPPED(tmpstat)) + } else if (WIFSTOPPED(tmpstat)) { tmpstat = (tmpstat & 0xffff00ff) | (bsd_to_linux_signal(WSTOPSIG(tmpstat)) << 8); - else if (WIFCONTINUED(tmpstat)) +#if defined(__amd64__) && !defined(COMPAT_LINUX32) + if (WSTOPSIG(status) == SIGTRAP) { + tmpstat = linux_ptrace_status(td, + siginfo.si_pid, tmpstat); + } +#endif + } else if (WIFCONTINUED(tmpstat)) { tmpstat = 0xffff; - error = copyout(&tmpstat, status, sizeof(int)); + } + error = copyout(&tmpstat, statusp, sizeof(int)); } return (error); @@ -931,7 +957,7 @@ int linux_wait4(struct thread *td, struct linux_wait4_args *args) { int error, options; - struct rusage ru, *rup; + struct __wrusage wru, *wrup; if (args->options & ~(LINUX_WUNTRACED | LINUX_WNOHANG | LINUX_WCONTINUED | __WCLONE | __WNOTHREAD | __WALL)) @@ -941,14 +967,14 @@ linux_wait4(struct thread *td, struct linux_wait4_args linux_to_bsd_waitopts(args->options, &options); if (args->rusage != NULL) - rup = &ru; + wrup = &wru; else - rup = NULL; - error = linux_common_wait(td, args->pid, args->status, options, rup); + wrup = NULL; + error = linux_common_wait(td, args->pid, args->status, options, wrup); if (error != 0) return (error); if (args->rusage != NULL) - error = linux_copyout_rusage(&ru, args->rusage); + error = linux_copyout_rusage(&wru.wru_self, args->rusage); return (error); } Modified: head/sys/compat/linux/linux_misc.h ============================================================================== --- head/sys/compat/linux/linux_misc.h Sun May 19 09:24:51 2019 (r347970) +++ head/sys/compat/linux/linux_misc.h Sun May 19 12:58:44 2019 (r347971) @@ -149,8 +149,9 @@ extern int stclohz; #define LINUX_GRND_NONBLOCK 0x0001 #define LINUX_GRND_RANDOM 0x0002 -int linux_common_wait(struct thread *td, int pid, int *status, - int options, struct rusage *ru); +#if defined(__amd64__) && !defined(COMPAT_LINUX32) +int linux_ptrace_status(struct thread *td, int pid, int status); +#endif void linux_to_bsd_waitopts(int options, int *bsdopts); int linux_set_upcall_kse(struct thread *td, register_t stack); int linux_set_cloned_tls(struct thread *td, void *desc);