From nobody Sat Nov 6 02:25:24 2021 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id A63E7183C595; Sat, 6 Nov 2021 02:25:26 +0000 (UTC) (envelope-from git@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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4HmLnd4TpMz3j7Z; Sat, 6 Nov 2021 02:25:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D147B22F6B; Sat, 6 Nov 2021 02:25:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1A62POI0077544; Sat, 6 Nov 2021 02:25:24 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1A62POhA077543; Sat, 6 Nov 2021 02:25:24 GMT (envelope-from git) Date: Sat, 6 Nov 2021 02:25:24 GMT Message-Id: <202111060225.1A62POhA077543@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 0303cc4be853 - stable/13 - Extract proc_get_binpath() from sysctl_kern_proc_pathname() List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 0303cc4be8538ae16c577cdeda30823ada76f802 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=0303cc4be8538ae16c577cdeda30823ada76f802 commit 0303cc4be8538ae16c577cdeda30823ada76f802 Author: Konstantin Belousov AuthorDate: 2021-10-29 01:42:59 +0000 Commit: Konstantin Belousov CommitDate: 2021-11-06 02:12:32 +0000 Extract proc_get_binpath() from sysctl_kern_proc_pathname() (cherry picked from commit f34fc6ba06a10e0f2a505ec0dd2f2fab2a79e53d) --- sys/kern/kern_proc.c | 89 +++++++++++++++++++++++++++++++++------------------- sys/sys/proc.h | 2 ++ 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index c4c01da1faea..2156c5c465ba 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -2226,41 +2226,34 @@ sysctl_kern_proc_auxv(SYSCTL_HANDLER_ARGS) } /* - * This sysctl allows a process to retrieve the path of the executable for - * itself or another process. + * Look up the canonical executable path running in the specified process. + * It tries to return the same hardlink name as was used for execve(2). + * This allows the programs that modify their behavior based on their progname, + * to operate correctly. + * + * Result is returned in retbuf, it must not be freed, similar to vn_fullpath() + * calling conventions. + * binname is a pointer to temporary string buffer of length MAXPATHLEN, + * allocated and freed by caller. + * freebuf should be freed by caller, from the M_TEMP malloc type. */ -static int -sysctl_kern_proc_pathname(SYSCTL_HANDLER_ARGS) +int +proc_get_binpath(struct proc *p, char *binname, char **retbuf, + char **freebuf) { - pid_t *pidp = (pid_t *)arg1; - unsigned int arglen = arg2; - struct proc *p; - struct vnode *vp, *dvp; - char *retbuf, *freebuf, *binname; struct nameidata nd; + struct vnode *vp, *dvp; size_t freepath_size; int error; bool do_fullpath; - if (arglen != 1) - return (EINVAL); - binname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); - binname[0] = '\0'; - if (*pidp == -1) { /* -1 means this process */ - p = req->td->td_proc; - } else { - error = pget(*pidp, PGET_CANSEE, &p); - if (error != 0) { - free(binname, M_TEMP); - return (error); - } - } + PROC_LOCK_ASSERT(p, MA_OWNED); vp = p->p_textvp; if (vp == NULL) { - if (*pidp != -1) - PROC_UNLOCK(p); - free(binname, M_TEMP); + PROC_UNLOCK(p); + *retbuf = NULL; + *freebuf = NULL; return (0); } vref(vp); @@ -2269,20 +2262,20 @@ sysctl_kern_proc_pathname(SYSCTL_HANDLER_ARGS) vref(dvp); if (p->p_binname != NULL) strlcpy(binname, p->p_binname, MAXPATHLEN); - if (*pidp != -1) - PROC_UNLOCK(p); + PROC_UNLOCK(p); + do_fullpath = true; - freebuf = NULL; + *freebuf = NULL; if (dvp != NULL && binname[0] != '\0') { freepath_size = MAXPATHLEN; if (vn_fullpath_hardlink(vp, dvp, binname, strlen(binname), - &retbuf, &freebuf, &freepath_size) == 0) { + retbuf, freebuf, &freepath_size) == 0) { /* * Recheck the looked up path. The binary * might have been renamed or replaced, in * which case we should not report old name. */ - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, retbuf, + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, *retbuf, req->td); error = namei(&nd); if (error == 0) { @@ -2294,13 +2287,43 @@ sysctl_kern_proc_pathname(SYSCTL_HANDLER_ARGS) } } if (do_fullpath) { - free(freebuf, M_TEMP); - freebuf = NULL; - error = vn_fullpath(vp, &retbuf, &freebuf); + free(*freebuf, M_TEMP); + *freebuf = NULL; + error = vn_fullpath(vp, retbuf, freebuf); } vrele(vp); if (dvp != NULL) vrele(dvp); + return (error); +} + +/* + * This sysctl allows a process to retrieve the path of the executable for + * itself or another process. + */ +static int +sysctl_kern_proc_pathname(SYSCTL_HANDLER_ARGS) +{ + pid_t *pidp = (pid_t *)arg1; + unsigned int arglen = arg2; + struct proc *p; + char *retbuf, *freebuf, *binname; + int error; + + if (arglen != 1) + return (EINVAL); + binname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); + binname[0] = '\0'; + if (*pidp == -1) { /* -1 means this process */ + error = 0; + p = req->td->td_proc; + PROC_LOCK(p); + } else { + error = pget(*pidp, PGET_CANSEE, &p); + } + + if (error == 0) + error = proc_get_binpath(p, binname, &retbuf, &freebuf); free(binname, M_TEMP); if (error != 0) return (error); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index a09a006b836b..96bd2cc8a6ce 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1115,6 +1115,8 @@ struct pargs *pargs_alloc(int len); void pargs_drop(struct pargs *pa); void pargs_hold(struct pargs *pa); void proc_add_orphan(struct proc *child, struct proc *parent); +int proc_get_binpath(struct proc *p, char *binname, char **fullpath, + char **freepath); int proc_getargv(struct thread *td, struct proc *p, struct sbuf *sb); int proc_getauxv(struct thread *td, struct proc *p, struct sbuf *sb); int proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb);