git: 930f2e4da964 - main - kern_execve(): avoid storing non-VDIR into p_textdvp
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 30 Jul 2026 02:56:39 UTC
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,