Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Apr 2023 15:47:50 GMT
From:      "Stephen J. Kiernan" <stevek@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 8512d82ea070 - main - veriexec: Additional functionality for MAC/veriexec
Message-ID:  <202304171547.33HFloTH070447@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by stevek:

URL: https://cgit.FreeBSD.org/src/commit/?id=8512d82ea0700df1c31232a0fe4c777d95600de3

commit 8512d82ea0700df1c31232a0fe4c777d95600de3
Author:     Steve Kiernan <stevek@juniper.net>
AuthorDate: 2023-04-02 19:33:10 +0000
Commit:     Stephen J. Kiernan <stevek@FreeBSD.org>
CommitDate: 2023-04-17 15:47:32 +0000

    veriexec: Additional functionality for MAC/veriexec
    
    Ensure veriexec opens the file before doing any read operations.
    
    When the MAC_VERIEXEC_CHECK_PATH_SYSCALL syscall is requested, veriexec
    needs to open the file before calling mac_veriexec_check_vp. This is to
    ensure any set up is done by the file system. Most file systems do not
    explicitly need an open, but some (e.g. virtfs) require initialization
    of access tokens (file identifiers, etc.) before doing any read or write
    operations.
    
    The evaluate_fingerprint() function needs to ensure it has an open file
    for reading in order to evaluate the fingerprint. The ideal solution is
    to have a hook after the VOP_OPEN call in vn_open. For now, we open the
    file for reading, envaluate the fingerprint, and close the file. While
    this leaves a potential hole that could possibly be taken advantage of
    by a dedicated aversary, this code path is not typically visited often
    in our use cases, as we primarily encounter verified mounts and not
    individual files. This should be considered a temporary workaround until
    discussions about the post-open hook have concluded and the hook becomes
    available.
    
    Add MAC_VERIEXEC_GET_PARAMS_PATH_SYSCALL and
    MAC_VERIEXEC_GET_PARAMS_PID_SYSCALL to mac_veriexec_syscall so we can
    fetch and check label contents in an unconstrained manner.
    
    Add a check for PRIV_VERIEXEC_CONTROL to do ioctl on /dev/veriexec
    
    Make it clear that trusted process cannot be debugged. Attempts to debug
    a trusted process already fail, but the failure path is very obscure.
    Add an explicit check for VERIEXEC_TRUSTED in
    mac_veriexec_proc_check_debug.
    
    We need mac_veriexec_priv_check to not block PRIV_KMEM_WRITE if
    mac_priv_gant() says it is ok.
    
    Reviewed by:    sjg
    Obtained from:  Juniper Networks, Inc.
---
 lib/libveriexec/Makefile                          |   4 +-
 lib/libveriexec/libveriexec.h                     |   8 +
 lib/libveriexec/veriexec_get.c                    | 184 ++++++++++++++++++++++
 sys/dev/veriexec/veriexec_ioctl.h                 |   5 +-
 sys/dev/veriexec/verified_exec.c                  |   2 +-
 sys/security/mac_veriexec/mac_veriexec.c          | 100 +++++++++++-
 sys/security/mac_veriexec/mac_veriexec.h          |  27 +++-
 sys/security/mac_veriexec/mac_veriexec_internal.h |   6 +-
 sys/security/mac_veriexec/veriexec_metadata.c     |  43 ++---
 sys/sys/priv.h                                    |   3 +-
 10 files changed, 343 insertions(+), 39 deletions(-)

diff --git a/lib/libveriexec/Makefile b/lib/libveriexec/Makefile
index 2c68faf3356f..84e2b8329967 100644
--- a/lib/libveriexec/Makefile
+++ b/lib/libveriexec/Makefile
@@ -8,7 +8,9 @@ INCS=		libveriexec.h
 
 WARNS?=		2
 
-SRCS=		veriexec_check.c
+SRCS= \
+	veriexec_check.c \
+	veriexec_get.c
 
 .include <bsd.lib.mk>
 
diff --git a/lib/libveriexec/libveriexec.h b/lib/libveriexec/libveriexec.h
index 42d2c964a174..d186db0ab8d9 100644
--- a/lib/libveriexec/libveriexec.h
+++ b/lib/libveriexec/libveriexec.h
@@ -29,9 +29,17 @@
 #ifndef __LIBVERIEXEC_H__
 #define __LIBVERIEXEC_H__
 
+struct mac_veriexec_syscall_params;
+
 int	veriexec_check_fd_mode(int, unsigned int);
 int	veriexec_check_path_mode(const char *, unsigned int);
 int	veriexec_check_fd(int);
 int	veriexec_check_path(const char *);
+int	veriexec_get_pid_params(pid_t, struct mac_veriexec_syscall_params *);
+int	veriexec_get_path_params(const char *,
+	    struct mac_veriexec_syscall_params *);
+int	veriexec_check_pid_label(pid_t, const char *);
+
+#define	HAVE_VERIEXEC_CHECK_PID_LABEL	1
 
 #endif  /* __LIBVERIEXEC_H__ */
diff --git a/lib/libveriexec/veriexec_get.c b/lib/libveriexec/veriexec_get.c
new file mode 100644
index 000000000000..46df6eecf76e
--- /dev/null
+++ b/lib/libveriexec/veriexec_get.c
@@ -0,0 +1,184 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021-2023, Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/mac.h>
+
+#include <unistd.h>
+#include <string.h>
+
+#include <security/mac_veriexec/mac_veriexec.h>
+
+/**
+ * @brief get veriexec params for a process
+ *
+ * @return
+ * @li 0 if successful
+ */
+int
+veriexec_get_pid_params(pid_t pid,
+    struct mac_veriexec_syscall_params *params)
+{
+	struct mac_veriexec_syscall_params_args args;
+
+	if (params == NULL)
+		return EINVAL;
+
+	args.u.pid = pid;
+	args.params = params;
+	return mac_syscall(MAC_VERIEXEC_NAME,
+	    MAC_VERIEXEC_GET_PARAMS_PID_SYSCALL, &args);
+}
+
+/**
+ * @brief get veriexec params for a process
+ *
+ * @return
+ * @li 0 if successful
+ */
+int
+veriexec_get_path_params(const char *file,
+    struct mac_veriexec_syscall_params *params)
+{
+	struct mac_veriexec_syscall_params_args args;
+
+	if (file == NULL || params == NULL)
+		return EINVAL;
+
+	args.u.filename = file;
+	args.params = params;
+	return mac_syscall(MAC_VERIEXEC_NAME,
+	    MAC_VERIEXEC_GET_PARAMS_PATH_SYSCALL, &args);
+}
+
+/**
+ * @brief check if label contains what we want
+ *
+ * @return
+ * @li 0 if no
+ * @li 1 if yes
+ */
+int
+veriexec_check_pid_label(pid_t pid, const char *want)
+{
+	struct mac_veriexec_syscall_params params;
+	char *cp;
+	size_t n;
+
+	if (want != NULL &&
+	    veriexec_get_pid_params(pid, &params) == 0) {
+		/* Does label contain [,]<want>[,] ? */
+		if (params.labellen > 0 &&
+		    (cp = strstr(params.label, want)) != NULL) {
+			if (cp == params.label || cp[-1] == ',') {
+				n = strlen(want);
+				if (cp[n] == '\0' || cp[n] == ',')
+					return 1; /* yes */
+			}
+		}
+	}
+	return 0;			/* no */
+}
+
+#ifdef UNIT_TEST
+#include <stdlib.h>
+#include <stdio.h>
+#include <err.h>
+
+static char *
+hash2hex(char *type, unsigned char *digest)
+{
+	static char buf[2*MAXFINGERPRINTLEN+1];
+	size_t n;
+	int i;
+
+	if (strcmp(type, "SHA1") == 0) {
+		n = 20;
+	} else if (strcmp(type, "SHA256") == 0) {
+		n = 32;
+	} else if (strcmp(type, "SHA384") == 0) {
+		n = 48;
+	}
+	for (i = 0; i < n; i++) {
+		sprintf(&buf[2*i], "%02x", (unsigned)digest[i]);
+	}
+	return buf;
+}
+
+int
+main(int argc, char *argv[])
+{
+	struct mac_veriexec_syscall_params params;
+	pid_t pid;
+	char *want = NULL;
+	int pflag = 0;
+	int error;
+	int c;
+
+	while ((c = getopt(argc, argv, "pw:")) != -1) {
+		switch (c) {
+		case 'p':
+			pflag = 1;
+			break;
+		case 'w':
+			want = optarg;
+			break;
+		default:
+			break;
+		}
+	}
+	for (; optind < argc; optind++) {
+
+		if (pflag) {
+			pid = atoi(argv[optind]);
+			if (want) {
+				error = veriexec_check_pid_label(pid, want);
+				printf("pid=%d want='%s': %d\n",
+				    pid, want, error);
+				continue;
+			}
+			error = veriexec_get_pid_params(pid, &params);
+		} else {
+			error = veriexec_get_path_params(argv[optind], &params);
+		}
+		if (error) {
+			err(2, "%s, error=%d", argv[optind], error);
+		}
+
+		printf("arg=%s, type=%s, flags=%u, label='%s', fingerprint='%s'\n",
+		    argv[optind], params.fp_type, (unsigned)params.flags,
+		    params.label,
+		    hash2hex(params.fp_type, params.fingerprint));
+	}
+	return 0;
+}
+#endif
diff --git a/sys/dev/veriexec/veriexec_ioctl.h b/sys/dev/veriexec/veriexec_ioctl.h
index 2fcccbb3c175..1409ebb9f40f 100644
--- a/sys/dev/veriexec/veriexec_ioctl.h
+++ b/sys/dev/veriexec/veriexec_ioctl.h
@@ -1,7 +1,7 @@
 /*
  * $FreeBSD$
  *
- * Copyright (c) 2011-2013, 2015, 2019, Juniper Networks, Inc.
+ * Copyright (c) 2011-2023, Juniper Networks, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,11 +34,8 @@
 #ifndef _DEV_VERIEXEC_VERIEXEC_IOCTL_H
 #define _DEV_VERIEXEC_VERIEXEC_IOCTL_H
 
-#include <sys/param.h>
 #include <security/mac_veriexec/mac_veriexec.h>
 
-#define	VERIEXEC_FPTYPELEN	16
-
 struct verified_exec_params  {
 	unsigned char flags;
 	char fp_type[VERIEXEC_FPTYPELEN];	/* type of fingerprint */
diff --git a/sys/dev/veriexec/verified_exec.c b/sys/dev/veriexec/verified_exec.c
index 1cb3cd75dbbe..c00aa49c2f6c 100644
--- a/sys/dev/veriexec/verified_exec.c
+++ b/sys/dev/veriexec/verified_exec.c
@@ -99,7 +99,7 @@ verifiedexecioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
 	 *
 	 * MAC/veriexec will grant kmem write privs to "trusted" processes.
 	 */
-	error = priv_check(td, PRIV_KMEM_WRITE);
+	error = priv_check(td, PRIV_VERIEXEC_CONTROL);
 	if (error)
 		return (error);
 
diff --git a/sys/security/mac_veriexec/mac_veriexec.c b/sys/security/mac_veriexec/mac_veriexec.c
index 52202f87f666..bae8c2b9055c 100644
--- a/sys/security/mac_veriexec/mac_veriexec.c
+++ b/sys/security/mac_veriexec/mac_veriexec.c
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2011, 2012, 2013, 2015, 2016, 2019 Juniper Networks, Inc.
+ * Copyright (c) 2011-2023 Juniper Networks, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -330,7 +330,10 @@ mac_veriexec_proc_check_debug(struct ucred *cred, struct proc *p)
 	if (error != 0)
 		return (0);
 
-	return ((flags & VERIEXEC_NOTRACE) ? EACCES : 0);
+	error = (flags & (VERIEXEC_NOTRACE|VERIEXEC_TRUSTED)) ? EACCES : 0;
+	MAC_VERIEXEC_DBG(4, "%s flags=%#x error=%d", __func__, flags, error);
+
+	return (error);
 }
 
 /**
@@ -406,6 +409,9 @@ mac_veriexec_kld_check_load(struct ucred *cred, struct vnode *vp,
  *  - PRIV_KMEM_WRITE\n
  *    Check if writes to /dev/mem and /dev/kmem are allowed\n
  *    (Only trusted processes are allowed)
+ *  - PRIV_VERIEXEC_CONTROL\n
+ *    Check if manipulating veriexec is allowed\n
+ *    (only trusted processes are allowed)
  *
  * @param cred		credentials to use
  * @param priv		privilege to check
@@ -415,20 +421,30 @@ mac_veriexec_kld_check_load(struct ucred *cred, struct vnode *vp,
 static int
 mac_veriexec_priv_check(struct ucred *cred, int priv)
 {
+	int error;
 
 	/* If we are not enforcing veriexec, nothing for us to check */
 	if ((mac_veriexec_state & VERIEXEC_STATE_ENFORCE) == 0)
 		return (0);
 
+	error = 0;
 	switch (priv) {
 	case PRIV_KMEM_WRITE:
-		if (!mac_veriexec_proc_is_trusted(cred, curproc))
-			return (EPERM);
+	case PRIV_VERIEXEC_CONTROL:
+		/*
+		 * Do not allow writing to memory or manipulating veriexec,
+		 * unless trusted
+		 */
+		if (mac_veriexec_proc_is_trusted(cred, curproc) == 0 &&
+		    mac_priv_grant(cred, priv) != 0)
+			error = EPERM;
+		MAC_VERIEXEC_DBG(4, "%s priv=%d error=%d", __func__, priv,
+		    error);
 		break;
 	default:
 		break;
 	}
-	return (0);
+	return (error);
 }
 
 /**
@@ -812,7 +828,24 @@ mac_veriexec_syscall(struct thread *td, int call, void *arg)
 	cap_rights_t rights;
 	struct vattr va;
 	struct file *fp;
-	int error;
+	struct mac_veriexec_syscall_params_args pargs;
+	struct mac_veriexec_syscall_params result;
+	struct mac_veriexec_file_info *ip;
+	struct proc *proc;
+	struct vnode *textvp;
+	int error, flags, proc_locked;
+
+	nd.ni_vp = NULL;
+	proc_locked = 0;
+	textvp = NULL;
+	switch (call) {
+	case MAC_VERIEXEC_GET_PARAMS_PID_SYSCALL:
+	case MAC_VERIEXEC_GET_PARAMS_PATH_SYSCALL:
+		error = copyin(arg, &pargs, sizeof(pargs));
+		if (error)
+			return error;
+		break;
+	}
 
 	switch (call) {
 	case MAC_VERIEXEC_CHECK_FD_SYSCALL:
@@ -863,18 +896,69 @@ cleanup_file:
 		NDINIT(&nd, LOOKUP,
 		    FOLLOW | LOCKLEAF | LOCKSHARED | AUDITVNODE1,
 		    UIO_USERSPACE, arg);
-		error = namei(&nd);
+		flags = FREAD;
+		error = vn_open(&nd, &flags, 0, NULL);
 		if (error != 0)
 			break;
 		NDFREE_PNBUF(&nd);
 
 		/* Check the fingerprint status of the vnode */
 		error = mac_veriexec_check_vp(td->td_ucred, nd.ni_vp, VVERIFY);
-		vput(nd.ni_vp);
+		/* nd.ni_vp cleaned up below */
+		break;
+	case MAC_VERIEXEC_GET_PARAMS_PID_SYSCALL:
+		if (pargs.u.pid == 0 || pargs.u.pid == curproc->p_pid) {
+			proc = curproc;
+		} else {
+			proc = pfind(pargs.u.pid);
+			if (proc == NULL)
+				return (EINVAL);
+			proc_locked = 1;
+		}
+		textvp = proc->p_textvp;
+		/* FALLTHROUGH */
+	case MAC_VERIEXEC_GET_PARAMS_PATH_SYSCALL:
+		if (textvp == NULL) {
+			/* Look up the path to get the vnode */
+			NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1,
+			    UIO_USERSPACE, pargs.u.filename);
+			flags = FREAD;
+			error = vn_open(&nd, &flags, 0, NULL);
+			if (error != 0)
+				break;
+
+			NDFREE_PNBUF(&nd);
+			textvp = nd.ni_vp;
+		}
+		error = VOP_GETATTR(textvp, &va, curproc->p_ucred);
+		if (proc_locked)
+			PROC_UNLOCK(proc);
+		if (error != 0)
+			break;
+
+		error = mac_veriexec_metadata_get_file_info(va.va_fsid,
+		    va.va_fileid, va.va_gen, NULL, &ip, FALSE);
+		if (error != 0)
+			break;
+
+		result.flags = ip->flags;
+		strlcpy(result.fp_type, ip->ops->type, sizeof(result.fp_type));
+		result.labellen = ip->labellen;
+		if (ip->labellen > 0)
+			strlcpy(result.label, ip->label, sizeof(result.label));
+		result.label[result.labellen] = '\0';
+		memcpy(result.fingerprint, ip->fingerprint,
+		    ip->ops->digest_len);
+
+		error = copyout(&result, pargs.params, sizeof(result));
 		break;
 	default:
 		error = EOPNOTSUPP;
 	}
+	if (nd.ni_vp != NULL) {
+		VOP_UNLOCK(nd.ni_vp);
+		vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
+	}
 	return (error);
 }
 
diff --git a/sys/security/mac_veriexec/mac_veriexec.h b/sys/security/mac_veriexec/mac_veriexec.h
index db5a13bbd06c..e4d336ce4ff4 100644
--- a/sys/security/mac_veriexec/mac_veriexec.h
+++ b/sys/security/mac_veriexec/mac_veriexec.h
@@ -29,6 +29,8 @@
 #ifndef	_SECURITY_MAC_VERIEXEC_H
 #define	_SECURITY_MAC_VERIEXEC_H
 
+#include <sys/param.h>
+
 #ifdef _KERNEL
 #include <sys/types.h>
 #include <sys/kernel.h>
@@ -42,8 +44,12 @@
 #define	MAC_VERIEXEC_NAME	"mac_veriexec"
 
 /* MAC/veriexec syscalls */
-#define	MAC_VERIEXEC_CHECK_FD_SYSCALL	1
-#define	MAC_VERIEXEC_CHECK_PATH_SYSCALL	2
+#define	MAC_VERIEXEC_CHECK_FD_SYSCALL		1
+#define	MAC_VERIEXEC_CHECK_PATH_SYSCALL		2
+#define	MAC_VERIEXEC_GET_PARAMS_PID_SYSCALL	3
+#define	MAC_VERIEXEC_GET_PARAMS_PATH_SYSCALL	4
+
+#define	VERIEXEC_FPTYPELEN	16	/* hash name */
 
 /**
  * Enough room for the largest signature...
@@ -68,6 +74,23 @@
 					     match signature */
 #define VERIEXEC_STATE_LOCKED	(1<<3)	/**< Do not allow further changes */
 
+/* for MAC_VERIEXEC_GET_PARAMS_*_SYSCALL */
+struct mac_veriexec_syscall_params  {
+	char fp_type[VERIEXEC_FPTYPELEN];
+	unsigned char fingerprint[MAXFINGERPRINTLEN];
+	char label[MAXLABELLEN];
+	size_t labellen;
+	unsigned char flags;
+};
+
+struct mac_veriexec_syscall_params_args {
+	union {
+		pid_t pid;
+		const char *filename;
+	} u;				/* input only */
+	struct mac_veriexec_syscall_params *params; /* result */
+};
+
 #ifdef _KERNEL
 /**
  * Version of the MAC/veriexec module
diff --git a/sys/security/mac_veriexec/mac_veriexec_internal.h b/sys/security/mac_veriexec/mac_veriexec_internal.h
index 6fc963a12393..e69f34df892e 100644
--- a/sys/security/mac_veriexec/mac_veriexec_internal.h
+++ b/sys/security/mac_veriexec/mac_veriexec_internal.h
@@ -78,9 +78,9 @@ int	mac_veriexec_metadata_get_executable_flags(struct ucred *cred,
 	    struct proc *p, int *flags, int check_files);
 int	mac_veriexec_metadata_get_file_flags(dev_t fsid, long fileid,
 	    unsigned long gen, int *flags, int check_files);
-struct mac_veriexec_file_info *
-	mac_veriexec_metadata_get_file_info(dev_t fsid, long fileid,
-	    unsigned long gen, int *found_dev, int check_files);
+int	mac_veriexec_metadata_get_file_info(dev_t fsid, long fileid,
+	    unsigned long gen, int *found_dev,
+	    struct mac_veriexec_file_info **ipp, int check_files);
 void	mac_veriexec_metadata_init(void);
 void	mac_veriexec_metadata_print_db(struct sbuf *sbp);
 int	mac_veriexec_metadata_unmounted(dev_t fsid, struct thread *td);
diff --git a/sys/security/mac_veriexec/veriexec_metadata.c b/sys/security/mac_veriexec/veriexec_metadata.c
index b5bfe70410d1..9e99f51e7e65 100644
--- a/sys/security/mac_veriexec/veriexec_metadata.c
+++ b/sys/security/mac_veriexec/veriexec_metadata.c
@@ -231,7 +231,7 @@ mac_veriexec_metadata_has_file(dev_t fsid, long fileid, unsigned long gen)
 {
 
 	return (mac_veriexec_metadata_get_file_info(fsid, fileid, gen, NULL,
-	    VERIEXEC_FILES_FIRST) != NULL);
+	    NULL, VERIEXEC_FILES_FIRST) == 0);
 }
 
 /**
@@ -438,12 +438,12 @@ mac_veriexec_metadata_get_file_flags(dev_t fsid, long fileid, unsigned long gen,
     int *flags, int check_files)
 {
 	struct mac_veriexec_file_info *ip;
-	int found_dev;
+	int error;
 
-	ip = mac_veriexec_metadata_get_file_info(fsid, fileid, gen, &found_dev,
-	    check_files);
-	if (ip == NULL)
-		return (ENOENT);
+	error = mac_veriexec_metadata_get_file_info(fsid, fileid, gen, NULL,
+	    &ip, check_files);
+	if (error != 0)
+		return (error);
 
 	*flags = ip->flags;
 	return (0);
@@ -513,9 +513,9 @@ mac_veriexec_metadata_fetch_fingerprint_status(struct vnode *vp,
 	status = mac_veriexec_get_fingerprint_status(vp);
 	if (status == FINGERPRINT_INVALID || status == FINGERPRINT_NODEV) {
 		found_dev = 0;
-		ip = mac_veriexec_metadata_get_file_info(vap->va_fsid,
-		    vap->va_fileid, vap->va_gen, &found_dev, check_files);
-		if (ip == NULL) {
+		error = mac_veriexec_metadata_get_file_info(vap->va_fsid,
+		    vap->va_fileid, vap->va_gen, &found_dev, &ip, check_files);
+		if (error != 0) {
 			status = (found_dev) ? FINGERPRINT_NOENTRY :
 			    FINGERPRINT_NODEV;
 			VERIEXEC_DEBUG(3,
@@ -735,19 +735,20 @@ search:
 /**
  * @brief Search the meta-data store for information on the specified file.
  *
- * @param fsid		file system identifier to look for
- * @param fileid	file to look for
- * @param gen		generation of file
+ * @param fsid          file system identifier to look for
+ * @param fileid        file to look for
+ * @param gen           generation of file
  * @param found_dev	indicator that an entry for the file system was found
- * @param check_files	if 1, check the files list first, otherwise check the
- * 			exectuables list first
+ * @param ipp           pointer to location to store the info pointer
+ * @param check_files   if 1, check the files list first, otherwise check the
+ *                      exectuables list first
  *
  * @return A pointer to the meta-data inforation if meta-data exists for
  *     the specified file identifier, otherwise @c NULL
  */
-struct mac_veriexec_file_info *
+int
 mac_veriexec_metadata_get_file_info(dev_t fsid, long fileid, unsigned long gen,
-    int *found_dev, int check_files)
+    int *found_dev, struct mac_veriexec_file_info **ipp, int check_files)
 {
 	struct veriexec_devhead *search[3];
 	struct mac_veriexec_file_info *ip;
@@ -763,14 +764,18 @@ mac_veriexec_metadata_get_file_info(dev_t fsid, long fileid, unsigned long gen,
 	}
 	search[2] = NULL;
 
-	VERIEXEC_DEBUG(3, ("%s: searching for dev %ju, file %lu\n",
-	    __func__, (uintmax_t)fsid, fileid));
+	VERIEXEC_DEBUG(3, ("%s: searching for dev %#jx, file %lu.%lu\n",
+	    __func__, (uintmax_t)fsid, fileid, gen));
 
 	/* Search for the specified file */
 	for (ip = NULL, x = 0; ip == NULL && search[x]; x++)
 		ip = get_veriexec_file(search[x], fsid, fileid, gen, found_dev);
 
-	return (ip);
+	if (ipp != NULL)
+		*ipp = ip;
+	if (ip == NULL)
+		return (ENOENT);
+	return (0);
 }
 
 /**
diff --git a/sys/sys/priv.h b/sys/sys/priv.h
index 6574d8c42599..fe2de892f97a 100644
--- a/sys/sys/priv.h
+++ b/sys/sys/priv.h
@@ -525,11 +525,12 @@
  */
 #define	PRIV_VERIEXEC_DIRECT	700	/* Can override 'indirect' */
 #define	PRIV_VERIEXEC_NOVERIFY	701	/* Can override O_VERIFY */
+#define	PRIV_VERIEXEC_CONTROL	702	/* Can configure veriexec */
 
 /*
  * Track end of privilege list.
  */
-#define	_PRIV_HIGHEST		702
+#define	_PRIV_HIGHEST		703
 
 /*
  * Validate that a named privilege is known by the privilege system.  Invalid



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202304171547.33HFloTH070447>