188a3358eSStephen J. Kiernan /*- 288a3358eSStephen J. Kiernan * SPDX-License-Identifier: BSD-2-Clause 3fb47a376SStephen J. Kiernan * 494288674SStephen J. Kiernan * Copyright (c) 2011, 2012, 2013, 2015, 2016, 2019, Juniper Networks, Inc. 5fb47a376SStephen J. Kiernan * All rights reserved. 6fb47a376SStephen J. Kiernan * 7fb47a376SStephen J. Kiernan * Redistribution and use in source and binary forms, with or without 8fb47a376SStephen J. Kiernan * modification, are permitted provided that the following conditions 9fb47a376SStephen J. Kiernan * are met: 10fb47a376SStephen J. Kiernan * 1. Redistributions of source code must retain the above copyright 11fb47a376SStephen J. Kiernan * notice, this list of conditions and the following disclaimer. 12fb47a376SStephen J. Kiernan * 2. Redistributions in binary form must reproduce the above copyright 13fb47a376SStephen J. Kiernan * notice, this list of conditions and the following disclaimer in the 14fb47a376SStephen J. Kiernan * documentation and/or other materials provided with the distribution. 15fb47a376SStephen J. Kiernan * 16fb47a376SStephen J. Kiernan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17fb47a376SStephen J. Kiernan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18fb47a376SStephen J. Kiernan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19fb47a376SStephen J. Kiernan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20fb47a376SStephen J. Kiernan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21fb47a376SStephen J. Kiernan * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22fb47a376SStephen J. Kiernan * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23fb47a376SStephen J. Kiernan * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24fb47a376SStephen J. Kiernan * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25fb47a376SStephen J. Kiernan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26fb47a376SStephen J. Kiernan * SUCH DAMAGE. 27fb47a376SStephen J. Kiernan */ 28fb47a376SStephen J. Kiernan 29fb47a376SStephen J. Kiernan #ifndef _SECURITY_MAC_VERIEXEC_H 30fb47a376SStephen J. Kiernan #define _SECURITY_MAC_VERIEXEC_H 31fb47a376SStephen J. Kiernan 328512d82eSSteve Kiernan #include <sys/param.h> 338512d82eSSteve Kiernan 34fb47a376SStephen J. Kiernan #ifdef _KERNEL 35fb47a376SStephen J. Kiernan #include <sys/types.h> 36fb47a376SStephen J. Kiernan #include <sys/kernel.h> 37fb47a376SStephen J. Kiernan #include <sys/queue.h> 38fb47a376SStephen J. Kiernan #include <sys/module.h> 39fb47a376SStephen J. Kiernan #endif 40fb47a376SStephen J. Kiernan 41fb47a376SStephen J. Kiernan /** 42fb47a376SStephen J. Kiernan * Name of the MAC module 43fb47a376SStephen J. Kiernan */ 44fb47a376SStephen J. Kiernan #define MAC_VERIEXEC_NAME "mac_veriexec" 45fb47a376SStephen J. Kiernan 46fb47a376SStephen J. Kiernan /* MAC/veriexec syscalls */ 47fb47a376SStephen J. Kiernan #define MAC_VERIEXEC_CHECK_FD_SYSCALL 1 48fb47a376SStephen J. Kiernan #define MAC_VERIEXEC_CHECK_PATH_SYSCALL 2 498512d82eSSteve Kiernan #define MAC_VERIEXEC_GET_PARAMS_PID_SYSCALL 3 508512d82eSSteve Kiernan #define MAC_VERIEXEC_GET_PARAMS_PATH_SYSCALL 4 518512d82eSSteve Kiernan 528512d82eSSteve Kiernan #define VERIEXEC_FPTYPELEN 16 /* hash name */ 53fb47a376SStephen J. Kiernan 54fb47a376SStephen J. Kiernan /** 55fb47a376SStephen J. Kiernan * Enough room for the largest signature... 56fb47a376SStephen J. Kiernan */ 57fb47a376SStephen J. Kiernan #define MAXFINGERPRINTLEN 64 /* enough room for largest signature */ 5894288674SStephen J. Kiernan #define MAXLABELLEN 128 59fb47a376SStephen J. Kiernan 60fb47a376SStephen J. Kiernan /* 61fb47a376SStephen J. Kiernan * Types of veriexec inodes we can have 62fb47a376SStephen J. Kiernan */ 63fb47a376SStephen J. Kiernan #define VERIEXEC_INDIRECT (1<<0) /* Only allow indirect execution */ 64fb47a376SStephen J. Kiernan #define VERIEXEC_FILE (1<<1) /* Fingerprint of a plain file */ 65fb47a376SStephen J. Kiernan #define VERIEXEC_NOTRACE (1<<2) /**< PTRACE not allowed */ 66fb47a376SStephen J. Kiernan #define VERIEXEC_TRUSTED (1<<3) /**< Safe to write /dev/mem */ 67fb47a376SStephen J. Kiernan #define VERIEXEC_NOFIPS (1<<4) /**< Not allowed in FIPS mode */ 6894288674SStephen J. Kiernan #define VERIEXEC_LABEL (1<<5) /**< We have a label */ 69fb47a376SStephen J. Kiernan 70fb47a376SStephen J. Kiernan #define VERIEXEC_STATE_INACTIVE 0 /**< Ignore */ 71fb47a376SStephen J. Kiernan #define VERIEXEC_STATE_LOADED (1<<0) /**< Sigs have been loaded */ 72fb47a376SStephen J. Kiernan #define VERIEXEC_STATE_ACTIVE (1<<1) /**< Pay attention to it */ 73fb47a376SStephen J. Kiernan #define VERIEXEC_STATE_ENFORCE (1<<2) /**< Fail execs for files that do not 74fb47a376SStephen J. Kiernan match signature */ 75fb47a376SStephen J. Kiernan #define VERIEXEC_STATE_LOCKED (1<<3) /**< Do not allow further changes */ 76fb47a376SStephen J. Kiernan 778512d82eSSteve Kiernan /* for MAC_VERIEXEC_GET_PARAMS_*_SYSCALL */ 788512d82eSSteve Kiernan struct mac_veriexec_syscall_params { 798512d82eSSteve Kiernan char fp_type[VERIEXEC_FPTYPELEN]; 808512d82eSSteve Kiernan unsigned char fingerprint[MAXFINGERPRINTLEN]; 818512d82eSSteve Kiernan char label[MAXLABELLEN]; 828512d82eSSteve Kiernan size_t labellen; 838512d82eSSteve Kiernan unsigned char flags; 848512d82eSSteve Kiernan }; 858512d82eSSteve Kiernan 868512d82eSSteve Kiernan struct mac_veriexec_syscall_params_args { 878512d82eSSteve Kiernan union { 888512d82eSSteve Kiernan pid_t pid; 898512d82eSSteve Kiernan const char *filename; 908512d82eSSteve Kiernan } u; /* input only */ 918512d82eSSteve Kiernan struct mac_veriexec_syscall_params *params; /* result */ 928512d82eSSteve Kiernan }; 938512d82eSSteve Kiernan 94fb47a376SStephen J. Kiernan #ifdef _KERNEL 95fb47a376SStephen J. Kiernan /** 96fb47a376SStephen J. Kiernan * Version of the MAC/veriexec module 97fb47a376SStephen J. Kiernan */ 9894288674SStephen J. Kiernan #define MAC_VERIEXEC_VERSION 2 99fb47a376SStephen J. Kiernan 100fb47a376SStephen J. Kiernan /* Valid states for the fingerprint flag - if signed exec is being used */ 101fb47a376SStephen J. Kiernan typedef enum fingerprint_status { 102fb47a376SStephen J. Kiernan FINGERPRINT_INVALID, /**< Fingerprint has not been evaluated */ 103fb47a376SStephen J. Kiernan FINGERPRINT_VALID, /**< Fingerprint evaluated and matches list */ 104fb47a376SStephen J. Kiernan FINGERPRINT_INDIRECT, /**< Fingerprint eval'd/matched but only 105fb47a376SStephen J. Kiernan indirect execs allowed */ 106fb47a376SStephen J. Kiernan FINGERPRINT_FILE, /**< Fingerprint evaluated/matched but 107fb47a376SStephen J. Kiernan not executable */ 108fb47a376SStephen J. Kiernan FINGERPRINT_NOMATCH, /**< Fingerprint evaluated but does not match */ 109fb47a376SStephen J. Kiernan FINGERPRINT_NOENTRY, /**< Fingerprint evaluated but no list entry */ 110fb47a376SStephen J. Kiernan FINGERPRINT_NODEV, /**< Fingerprint evaluated but no dev list */ 111fb47a376SStephen J. Kiernan } fingerprint_status_t; 112fb47a376SStephen J. Kiernan 113fb47a376SStephen J. Kiernan typedef void (*mac_veriexec_fpop_init_t)(void *); 114fb47a376SStephen J. Kiernan typedef void (*mac_veriexec_fpop_update_t)(void *, const uint8_t *, size_t); 115fb47a376SStephen J. Kiernan typedef void (*mac_veriexec_fpop_final_t)(uint8_t *, void *); 116fb47a376SStephen J. Kiernan 117fb47a376SStephen J. Kiernan struct mac_veriexec_fpops { 118fb47a376SStephen J. Kiernan const char *type; 119fb47a376SStephen J. Kiernan size_t digest_len; 120fb47a376SStephen J. Kiernan size_t context_size; 121fb47a376SStephen J. Kiernan mac_veriexec_fpop_init_t init; 122fb47a376SStephen J. Kiernan mac_veriexec_fpop_update_t update; 123fb47a376SStephen J. Kiernan mac_veriexec_fpop_final_t final; 124fb47a376SStephen J. Kiernan LIST_ENTRY(mac_veriexec_fpops) entries; 125fb47a376SStephen J. Kiernan }; 126fb47a376SStephen J. Kiernan 127fb47a376SStephen J. Kiernan /** 128fb47a376SStephen J. Kiernan * Verified execution subsystem debugging level 129fb47a376SStephen J. Kiernan */ 130fb47a376SStephen J. Kiernan extern int mac_veriexec_debug; 131fb47a376SStephen J. Kiernan 132fb47a376SStephen J. Kiernan /** 133fb47a376SStephen J. Kiernan * @brief Define a fingerprint module. 134fb47a376SStephen J. Kiernan * 135fb47a376SStephen J. Kiernan * @param _name Name of the fingerprint module 136fb47a376SStephen J. Kiernan * @param _digest_len Length of the digest string, in number of characters 137fb47a376SStephen J. Kiernan * @param _context_size Size of the context structure, in bytes 138fb47a376SStephen J. Kiernan * @param _init Initialization function of type 139fb47a376SStephen J. Kiernan * mac_veriexec_fpop_init_t 140fb47a376SStephen J. Kiernan * @param _update Update function of type mac_veriexec_fpop_update_t 141fb47a376SStephen J. Kiernan * @param _final Finalize function of type mac_veriexec_fpop_final_t 142fb47a376SStephen J. Kiernan * @param _vers Module version 143fb47a376SStephen J. Kiernan */ 144fb47a376SStephen J. Kiernan #define MAC_VERIEXEC_FPMOD(_name, _digest_len, _context_size, _init, \ 145fb47a376SStephen J. Kiernan _update, _final, _vers) \ 146fb47a376SStephen J. Kiernan static struct mac_veriexec_fpops \ 147fb47a376SStephen J. Kiernan mac_veriexec_##_name##_fpops = { \ 148fb47a376SStephen J. Kiernan .type = #_name, \ 149fb47a376SStephen J. Kiernan .digest_len = _digest_len, \ 150fb47a376SStephen J. Kiernan .context_size = _context_size, \ 151fb47a376SStephen J. Kiernan .init = _init, \ 152fb47a376SStephen J. Kiernan .update = _update, \ 153fb47a376SStephen J. Kiernan .final = _final, \ 154fb47a376SStephen J. Kiernan }; \ 155fb47a376SStephen J. Kiernan static moduledata_t mac_veriexec_##_name##_mod = { \ 156fb47a376SStephen J. Kiernan "mac_veriexec/" #_name, \ 157fb47a376SStephen J. Kiernan mac_veriexec_fingerprint_modevent, \ 158fb47a376SStephen J. Kiernan &(mac_veriexec_##_name##_fpops) \ 159fb47a376SStephen J. Kiernan }; \ 160fb47a376SStephen J. Kiernan MODULE_VERSION(mac_veriexec_##_name, _vers); \ 161fb47a376SStephen J. Kiernan DECLARE_MODULE(mac_veriexec_##_name, \ 162fb47a376SStephen J. Kiernan mac_veriexec_##_name##_mod, SI_SUB_MAC_POLICY, \ 163fb47a376SStephen J. Kiernan SI_ORDER_ANY); \ 164fb47a376SStephen J. Kiernan MODULE_DEPEND(mac_veriexec_##_name, mac_veriexec, \ 165fb47a376SStephen J. Kiernan MAC_VERIEXEC_VERSION, MAC_VERIEXEC_VERSION, \ 166fb47a376SStephen J. Kiernan MAC_VERIEXEC_VERSION) 167fb47a376SStephen J. Kiernan 168fb47a376SStephen J. Kiernan /* 169fb47a376SStephen J. Kiernan * The following function should not be called directly. The prototype is 170fb47a376SStephen J. Kiernan * included here to satisfy the compiler when using the macro above. 171fb47a376SStephen J. Kiernan */ 172fb47a376SStephen J. Kiernan int mac_veriexec_fingerprint_modevent(module_t mod, int type, void *data); 173fb47a376SStephen J. Kiernan 174fb47a376SStephen J. Kiernan /* 175fb47a376SStephen J. Kiernan * Public functions 176fb47a376SStephen J. Kiernan */ 177fb47a376SStephen J. Kiernan int mac_veriexec_metadata_add_file(int file_dev, dev_t fsid, long fileid, 178fb47a376SStephen J. Kiernan unsigned long gen, unsigned char fingerprint[MAXFINGERPRINTLEN], 17994288674SStephen J. Kiernan char *label, size_t labellen, int flags, const char *fp_type, 18094288674SStephen J. Kiernan int override); 181*48ffacbcSSteve Kiernan const char *mac_veriexec_metadata_get_file_label(dev_t fsid, long fileid, 182*48ffacbcSSteve Kiernan unsigned long gen, int check_files); 183fb47a376SStephen J. Kiernan int mac_veriexec_metadata_has_file(dev_t fsid, long fileid, 184fb47a376SStephen J. Kiernan unsigned long gen); 185fb47a376SStephen J. Kiernan int mac_veriexec_proc_is_trusted(struct ucred *cred, struct proc *p); 186fb47a376SStephen J. Kiernan #endif 187fb47a376SStephen J. Kiernan 188fb47a376SStephen J. Kiernan #endif /* _SECURITY_MAC_VERIEXEC_H */ 189