diff --git a/sys/security/mac_veriexec/mac_veriexec.c b/sys/security/mac_veriexec/mac_veriexec.c --- a/sys/security/mac_veriexec/mac_veriexec.c +++ b/sys/security/mac_veriexec/mac_veriexec.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include "mac_veriexec.h" @@ -430,6 +431,18 @@ return (0); } +/** + * @internal + * @brief Check if the requested sysctl should be allowed + * + * @param cred credentials to use + * @param oidp sysctl OID + * @param arg1 first sysctl argument + * @param arg2 second sysctl argument + * @param req sysctl request information + * + * @return 0 if the sysctl should be allowed, otherwise an error code. + */ static int mac_veriexec_sysctl_check(struct ucred *cred, struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req) @@ -533,6 +546,9 @@ return (error); break; default: + /* Allow for overriding verification requirement */ + if (mac_priv_grant(cred, PRIV_VERIEXEC_NOVERIFY) == 0) + return (0); /* * Caller wants open to fail unless there is a valid * fingerprint registered. diff --git a/sys/security/mac_veriexec/veriexec_fingerprint.c b/sys/security/mac_veriexec/veriexec_fingerprint.c --- a/sys/security/mac_veriexec/veriexec_fingerprint.c +++ b/sys/security/mac_veriexec/veriexec_fingerprint.c @@ -42,11 +42,14 @@ #include #include #include +#include #include #include #include #include +#include + #include "mac_veriexec.h" #include "mac_veriexec_internal.h" @@ -292,7 +295,8 @@ case FINGERPRINT_INDIRECT: /* fingerprint ok but need to check for direct execution */ - if (!imgp->interpreted) { + if (!imgp->interpreted && + mac_priv_grant(td->td_ucred, PRIV_VERIEXEC_DIRECT) != 0) { identify_error(imgp, td, "attempted direct execution"); if (prison0.pr_securelevel > 1 || mac_veriexec_in_state(VERIEXEC_STATE_ENFORCE)) @@ -326,6 +330,23 @@ identify_error(imgp, td, "invalid status field for vnode"); error = EPERM; } + switch (status) { + case FINGERPRINT_NODEV: + case FINGERPRINT_NOENTRY: + /* + * Check if this process has override allowed. + * This will only be true if PRIV_VERIEXEC_DIRECT + * already succeeded. + */ + if (error == EAUTH && + mac_priv_grant(td->td_ucred, PRIV_VERIEXEC_NOVERIFY) == 0) { + error = 0; + } + break; + default: + break; + } + return error; } diff --git a/sys/sys/priv.h b/sys/sys/priv.h --- a/sys/sys/priv.h +++ b/sys/sys/priv.h @@ -520,10 +520,16 @@ */ #define PRIV_KDB_SET_BACKEND 690 /* Allow setting KDB backend. */ +/* + * veriexec override privileges - very rare! + */ +#define PRIV_VERIEXEC_DIRECT 700 /* Can override 'indirect' */ +#define PRIV_VERIEXEC_NOVERIFY 701 /* Can override O_VERIFY */ + /* * Track end of privilege list. */ -#define _PRIV_HIGHEST 691 +#define _PRIV_HIGHEST 702 /* * Validate that a named privilege is known by the privilege system. Invalid