From nobody Sat Nov 06 02:25:21 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 69FC9183BE60; Sat, 6 Nov 2021 02:25:22 +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 4HmLnY5y3Gz3jDS; Sat, 6 Nov 2021 02:25:21 +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 689A02311E; Sat, 6 Nov 2021 02:25:21 +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 1A62PLqf077472; Sat, 6 Nov 2021 02:25:21 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1A62PLl1077471; Sat, 6 Nov 2021 02:25:21 GMT (envelope-from git) Date: Sat, 6 Nov 2021 02:25:21 GMT Message-Id: <202111060225.1A62PLl1077471@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: d39bd6d14d4e - stable/13 - exec: store parent directory and hardlink name of the binary in struct proc 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: d39bd6d14d4ebf185a5557bb2206eb2cd7b4cb0f Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=d39bd6d14d4ebf185a5557bb2206eb2cd7b4cb0f commit d39bd6d14d4ebf185a5557bb2206eb2cd7b4cb0f Author: Konstantin Belousov AuthorDate: 2021-10-23 18:44:22 +0000 Commit: Konstantin Belousov CommitDate: 2021-11-06 02:12:32 +0000 exec: store parent directory and hardlink name of the binary in struct proc (cherry picked from commit 351d5f7fc5161ededeaa226ee3f21a438ee4a632) --- sys/kern/kern_exec.c | 108 +++++++++++++++++++++++++++++---------------------- sys/kern/kern_exit.c | 10 ++++- sys/kern/kern_fork.c | 12 +++++- sys/sys/proc.h | 2 + 4 files changed, 82 insertions(+), 50 deletions(-) diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index a82eefca62b7..cf7af148f5c8 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -390,7 +390,9 @@ do_execve(struct thread *td, struct image_args *args, struct mac *mac_p, #ifdef KTRACE struct ktr_io_params *kiop; #endif - struct vnode *oldtextvp = NULL, *newtextvp; + struct vnode *oldtextvp, *newtextvp; + struct vnode *oldtextdvp, *newtextdvp; + char *oldbinname, *newbinname; bool credential_changing; #ifdef MAC struct label *interpvplabel = NULL; @@ -405,6 +407,9 @@ do_execve(struct thread *td, struct image_args *args, struct mac *mac_p, static const char fexecv_proc_title[] = "(fexecv)"; imgp = &image_params; + oldtextvp = oldtextdvp = NULL; + newtextvp = newtextdvp = NULL; + newbinname = oldbinname = NULL; #ifdef KTRACE kiop = NULL; #endif @@ -439,19 +444,6 @@ do_execve(struct thread *td, struct image_args *args, struct mac *mac_p, goto exec_fail; #endif - /* - * Translate the file name. namei() returns a vnode pointer - * in ni_vp among other things. - * - * XXXAUDIT: It would be desirable to also audit the name of the - * interpreter if this is an interpreted binary. - */ - if (args->fname != NULL) { - NDINIT(&nd, LOOKUP, ISOPEN | LOCKLEAF | LOCKSHARED | FOLLOW | - SAVENAME | AUDITVNODE1 | WANTPARENT, - UIO_SYSSPACE, args->fname, td); - } - SDT_PROBE1(proc, , , exec, args->fname); interpret: @@ -468,12 +460,42 @@ interpret: goto exec_fail; } #endif + + /* + * Translate the file name. namei() returns a vnode + * pointer in ni_vp among other things. + */ + NDINIT(&nd, LOOKUP, ISOPEN | LOCKLEAF | LOCKSHARED | FOLLOW | + SAVENAME | AUDITVNODE1 | WANTPARENT, UIO_SYSSPACE, + args->fname, td); + error = namei(&nd); if (error) goto exec_fail; newtextvp = nd.ni_vp; + newtextdvp = nd.ni_dvp; + nd.ni_dvp = NULL; + newbinname = malloc(nd.ni_cnd.cn_namelen + 1, M_PARGS, + M_WAITOK); + memcpy(newbinname, nd.ni_cnd.cn_nameptr, nd.ni_cnd.cn_namelen); + newbinname[nd.ni_cnd.cn_namelen] = '\0'; imgp->vp = newtextvp; + + /* + * Do the best to calculate the full path to the image file. + */ + if (args->fname[0] == '/') { + imgp->execpath = args->fname; + } else { + VOP_UNLOCK(imgp->vp); + freepath_size = MAXPATHLEN; + if (vn_fullpath_hardlink(newtextvp, newtextdvp, + newbinname, nd.ni_cnd.cn_namelen, &imgp->execpath, + &imgp->freepath, &freepath_size) != 0) + imgp->execpath = args->fname; + vn_lock(imgp->vp, LK_SHARED | LK_RETRY); + } } else { AUDIT_ARG_FD(args->fd); /* @@ -483,6 +505,9 @@ interpret: &newtextvp); if (error) goto exec_fail; + if (vn_fullpath(imgp->vp, &imgp->execpath, + &imgp->freepath) != 0) + imgp->execpath = args->fname; vn_lock(newtextvp, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(newtextvp); imgp->vp = newtextvp; @@ -591,28 +616,6 @@ interpret: } /* The new credentials are installed into the process later. */ - /* - * Do the best to calculate the full path to the image file. - */ - if (args->fname != NULL) { - if (args->fname[0] == '/') { - imgp->execpath = args->fname; - } else { - VOP_UNLOCK(imgp->vp); - freepath_size = MAXPATHLEN; - if (vn_fullpath_hardlink(&nd, &imgp->execpath, - &imgp->freepath, &freepath_size) != 0) - imgp->execpath = args->fname; - vn_lock(imgp->vp, LK_SHARED | LK_RETRY); - } - } else { - VOP_UNLOCK(imgp->vp); - if (vn_fullpath(imgp->vp, &imgp->execpath, - &imgp->freepath) != 0) - imgp->execpath = args->fname; - vn_lock(imgp->vp, LK_SHARED | LK_RETRY); - } - /* * If the current process has a special image activator it * wants to try first, call it. For example, emulating shell @@ -666,10 +669,15 @@ interpret: imgp->opened = false; } vput(newtextvp); + imgp->vp = newtextvp = NULL; if (args->fname != NULL) { - if (nd.ni_dvp != NULL) - vrele(nd.ni_dvp); + if (newtextdvp != NULL) { + vrele(newtextdvp); + newtextdvp = NULL; + } NDFREE(&nd, NDF_ONLY_PNBUF); + free(newbinname, M_PARGS); + newbinname = NULL; } vm_object_deallocate(imgp->object); imgp->object = NULL; @@ -679,9 +687,6 @@ interpret: imgp->freepath = NULL; /* set new name to that of the interpreter */ args->fname = imgp->interpreter_name; - NDINIT(&nd, LOOKUP, ISOPEN | LOCKLEAF | LOCKSHARED | FOLLOW | - SAVENAME | WANTPARENT, - UIO_SYSSPACE, imgp->interpreter_name, td); goto interpret; } @@ -853,11 +858,17 @@ interpret: } /* - * Store the vp for use in procfs. This vnode was referenced by namei - * or fgetvp_exec. + * Store the vp for use in kern.proc.pathname. This vnode was + * referenced by namei() or fgetvp_exec(). */ oldtextvp = p->p_textvp; p->p_textvp = newtextvp; + oldtextdvp = p->p_textdvp; + p->p_textdvp = newtextdvp; + newtextdvp = NULL; + oldbinname = p->p_binname; + p->p_binname = newbinname; + newbinname = NULL; #ifdef KDTRACE_HOOKS /* @@ -930,11 +941,11 @@ exec_fail_dealloc: vput(imgp->vp); else VOP_UNLOCK(imgp->vp); - if (args->fname != NULL) { - if (nd.ni_dvp != NULL) - vrele(nd.ni_dvp); + if (args->fname != NULL) NDFREE(&nd, NDF_ONLY_PNBUF); - } + if (newtextdvp != NULL) + vrele(newtextdvp); + free(newbinname, M_PARGS); } if (imgp->object != NULL) @@ -973,6 +984,9 @@ exec_fail: */ if (oldtextvp != NULL) vrele(oldtextvp); + if (oldtextdvp != NULL) + vrele(oldtextdvp); + free(oldbinname, M_PARGS); #ifdef KTRACE ktr_io_params_free(kiop); #endif diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 47ead49bb202..0b3265cac6f1 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -424,12 +424,20 @@ exit1(struct thread *td, int rval, int signo) ktrprocexit(td); #endif /* - * Release reference to text vnode + * Release reference to text vnode etc */ if (p->p_textvp != NULL) { vrele(p->p_textvp); p->p_textvp = NULL; } + if (p->p_textdvp != NULL) { + vrele(p->p_textdvp); + p->p_textdvp = NULL; + } + if (p->p_binname != NULL) { + free(p->p_binname, M_PARGS); + p->p_binname = NULL; + } /* * Release our limits structure. diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index b2d58e804123..74b415a838ee 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -526,6 +526,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread * } p2->p_textvp = p1->p_textvp; + p2->p_textdvp = p1->p_textdvp; p2->p_fd = fd; p2->p_fdtol = fdtol; p2->p_pd = pd; @@ -547,9 +548,16 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread * PROC_UNLOCK(p1); PROC_UNLOCK(p2); - /* Bump references to the text vnode (for procfs). */ - if (p2->p_textvp) + /* + * Bump references to the text vnode and directory, and copy + * the hardlink name. + */ + if (p2->p_textvp != NULL) vrefact(p2->p_textvp); + if (p2->p_textdvp != NULL) + vrefact(p2->p_textdvp); + p2->p_binname = p1->p_binname == NULL ? NULL : + strdup(p1->p_binname, M_PARGS); /* * Set up linkage for kernel based threading. diff --git a/sys/sys/proc.h b/sys/sys/proc.h index b647cb1c33ef..df09f3f5d86d 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -723,6 +723,8 @@ struct proc { LIST_HEAD(, proc) p_orphans; /* (e) Pointer to list of orphans. */ TAILQ_HEAD(, kq_timer_cb_data) p_kqtim_stop; /* (c) */ + struct vnode *p_textdvp; /* (b) Dir containing textvp. */ + char *p_binname; /* (b) Binary hardlink name. */ }; #define p_session p_pgrp->pg_session