git: ee92c8a842d6 - main - sysctl kern.proc.procname: report right hardlink name
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 28 Oct 2021 17:50:43 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=ee92c8a842d61ffda8d111e1b0e398085c5bfb3a commit ee92c8a842d61ffda8d111e1b0e398085c5bfb3a Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-10-23 19:01:37 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-10-28 17:50:02 +0000 sysctl kern.proc.procname: report right hardlink name PR: 248184 Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D32611 --- sys/kern/kern_proc.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 2649d1d3a58f..c4c01da1faea 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <sys/elf.h> #include <sys/eventhandler.h> #include <sys/exec.h> +#include <sys/fcntl.h> #include <sys/jail.h> #include <sys/kernel.h> #include <sys/limits.h> @@ -54,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include <sys/mman.h> #include <sys/mount.h> #include <sys/mutex.h> +#include <sys/namei.h> #include <sys/proc.h> #include <sys/ptrace.h> #include <sys/refcount.h> @@ -2233,32 +2235,74 @@ sysctl_kern_proc_pathname(SYSCTL_HANDLER_ARGS) pid_t *pidp = (pid_t *)arg1; unsigned int arglen = arg2; struct proc *p; - struct vnode *vp; - char *retbuf, *freebuf; + struct vnode *vp, *dvp; + char *retbuf, *freebuf, *binname; + struct nameidata nd; + 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) + if (error != 0) { + free(binname, M_TEMP); return (error); + } } vp = p->p_textvp; if (vp == NULL) { if (*pidp != -1) PROC_UNLOCK(p); + free(binname, M_TEMP); return (0); } vref(vp); + dvp = p->p_textdvp; + if (dvp != NULL) + vref(dvp); + if (p->p_binname != NULL) + strlcpy(binname, p->p_binname, MAXPATHLEN); if (*pidp != -1) PROC_UNLOCK(p); - error = vn_fullpath(vp, &retbuf, &freebuf); + do_fullpath = true; + 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) { + /* + * 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, + req->td); + error = namei(&nd); + if (error == 0) { + if (nd.ni_vp == vp) + do_fullpath = false; + vrele(nd.ni_vp); + NDFREE(&nd, NDF_ONLY_PNBUF); + } + } + } + if (do_fullpath) { + free(freebuf, M_TEMP); + freebuf = NULL; + error = vn_fullpath(vp, &retbuf, &freebuf); + } vrele(vp); - if (error) + if (dvp != NULL) + vrele(dvp); + free(binname, M_TEMP); + if (error != 0) return (error); error = SYSCTL_OUT(req, retbuf, strlen(retbuf) + 1); free(freebuf, M_TEMP);