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
This commit is contained in:
parent
351d5f7fc5
commit
ee92c8a842
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user