Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Jul 2026 02:56:39 +0000
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 930f2e4da964 - main - kern_execve(): avoid storing non-VDIR into p_textdvp
Message-ID:  <6a6abd67.1a0ec.3ddbcc03@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=930f2e4da96487f18a82f912275c6302c39b9bd2

commit 930f2e4da96487f18a82f912275c6302c39b9bd2
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-07-27 16:58:31 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-07-30 02:56:30 +0000

    kern_execve(): avoid storing non-VDIR into p_textdvp
    
    Reported by:    Nick Price
    Tested by:      pho
    Reviewed by:    jah, markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D58506
---
 sys/kern/kern_exec.c | 38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 35eb22e03f48..352170d4f6f0 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -32,12 +32,12 @@
 #include "opt_ktrace.h"
 #include "opt_vm.h"
 
-#include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/acct.h>
 #include <sys/asan.h>
 #include <sys/capsicum.h>
 #include <sys/compressor.h>
+#include <sys/dirent.h>
 #include <sys/eventhandler.h>
 #include <sys/exec.h>
 #include <sys/fcntl.h>
@@ -568,12 +568,46 @@ interpret:
 		newbinname[nd.ni_cnd.cn_namelen] = '\0';
 		imgp->vp = newtextvp;
 
+		if (atomic_load_8(&newtextdvp->v_type) != VDIR) {
+			struct vnode *dvp1;
+			char *buf1;
+			size_t buf1len;
+
+			/*
+			 * The newtextdvp vnode might be not a
+			 * directory when reclaimed or when the image
+			 * is mounted over a regular file.  In the
+			 * latter case, try to resolve the containing
+			 * directory.
+			 *
+			 * In any case, p_textdvp must be either a
+			 * directory or reclaimed.
+			 */
+			VOP_UNLOCK(imgp->vp);
+			dvp1 = newtextdvp;
+			buf1len = MAXNAMLEN + 1;
+			buf1 = malloc(buf1len, M_TEMP, M_WAITOK);
+			error = vn_vptocnp(&dvp1, buf1, &buf1len);
+			if (error == 0) {
+				if (atomic_load_8(&dvp1->v_type) == VDIR) {
+					newtextdvp = dvp1;
+				} else {
+					vrele(dvp1);
+					newtextdvp = NULL;
+				}
+			} else {
+				newtextdvp = NULL;
+			}
+			free(buf1, M_TEMP);
+			vn_lock(imgp->vp, LK_SHARED | LK_RETRY);
+		}
+
 		/*
 		 * Do the best to calculate the full path to the image file.
 		 */
 		if (args->fname[0] == '/') {
 			imgp->execpath = args->fname;
-		} else {
+		} else if (newtextdvp != NULL) {
 			VOP_UNLOCK(imgp->vp);
 			freepath_size = MAXPATHLEN;
 			if (vn_fullpath_hardlink(newtextvp, newtextdvp,


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6abd67.1a0ec.3ddbcc03>