The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_verifiedexec.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: kern_verifiedexec.c,v 1.9.2.31 2007/06/26 17:00:47 ghen Exp $  */
    2 
    3 /*-
    4  * Copyright 2005 Elad Efrat <elad@bsd.org.il>
    5  * Copyright 2005 Brett Lymn <blymn@netbsd.org>
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Brett Lymn and Elad Efrat
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Neither the name of The NetBSD Foundation nor the names of its
   16  *    contributors may be used to endorse or promote products derived
   17  *    from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.9.2.31 2007/06/26 17:00:47 ghen Exp $");
   34 
   35 #include "opt_verified_exec.h"
   36 
   37 #include <sys/param.h>
   38 #include <sys/mount.h>
   39 #include <sys/malloc.h>
   40 #include <sys/vnode.h>
   41 #include <sys/namei.h>
   42 #include <sys/exec.h>
   43 #include <sys/proc.h>
   44 #include <sys/syslog.h>
   45 #include <sys/sysctl.h>
   46 #define VERIEXEC_NEED_NODE
   47 #include <sys/verified_exec.h>
   48 #if defined(__FreeBSD__)
   49 # include <sys/systm.h>
   50 # include <sys/imgact.h>
   51 # include <crypto/sha1.h>
   52 #else
   53 # include <sys/sha1.h>
   54 #endif
   55 #include "crypto/sha2/sha2.h"
   56 #include "crypto/ripemd160/rmd160.h"
   57 #include <sys/md5.h>
   58 
   59 int veriexec_verbose = 0;
   60 int veriexec_strict = 0;
   61 
   62 char *veriexec_fp_names = NULL;
   63 unsigned int veriexec_name_max = 0;
   64 
   65 struct sysctlnode *veriexec_count_node = NULL;
   66 
   67 /* Veriexecs table of hash types and their associated information. */
   68 LIST_HEAD(veriexec_ops_head, veriexec_fp_ops) veriexec_ops_list;
   69 
   70 /*
   71  * Add fingerprint names to the global list.
   72  */
   73 static void
   74 veriexec_add_fp_name(char *name)
   75 {
   76         char *newp;
   77         unsigned int new_max;
   78 
   79         if (name == NULL)
   80                 return;
   81 
   82         if (veriexec_fp_names == NULL) {
   83                 veriexec_name_max = (VERIEXEC_TYPE_MAXLEN + 1) * 6;
   84                 veriexec_fp_names = malloc(veriexec_name_max, M_TEMP, M_WAITOK);
   85                 memset(veriexec_fp_names, 0, veriexec_name_max);
   86         }
   87 
   88         if ((strlen(veriexec_fp_names) + VERIEXEC_TYPE_MAXLEN + 1) >=
   89             veriexec_name_max) {
   90                 new_max = veriexec_name_max + 4 * (VERIEXEC_TYPE_MAXLEN + 1);
   91                 newp = realloc(veriexec_fp_names, new_max, M_TEMP, M_WAITOK);
   92                 veriexec_fp_names = newp;
   93                 veriexec_name_max = new_max;
   94         }
   95 
   96         strlcat(veriexec_fp_names, name, veriexec_name_max);
   97         strlcat(veriexec_fp_names, " ", veriexec_name_max);
   98 }
   99 
  100 /*
  101  * Add ops to the fignerprint ops vector list.
  102  */
  103 int veriexec_add_fp_ops(struct veriexec_fp_ops *ops)
  104 {
  105         if (ops == NULL)
  106                 return (EFAULT);
  107 
  108         if ((ops->init == NULL) ||
  109             (ops->update == NULL) ||
  110             (ops->final == NULL))
  111                 return (EFAULT);
  112 
  113         ops->type[sizeof(ops->type) - 1] = '\0';
  114 
  115 #ifdef DIAGNOSTIC
  116         if (veriexec_find_ops(ops->type) != NULL)
  117                 return (EEXIST);
  118 #endif /* DIAGNOSTIC */
  119 
  120         LIST_INSERT_HEAD(&veriexec_ops_list, ops, entries);
  121         veriexec_add_fp_name(ops->type);
  122 
  123         return (0);
  124 }
  125 
  126 /*
  127  * Initialise the internal "default" fingerprint ops vector list.
  128  */
  129 void
  130 veriexec_init_fp_ops(void)
  131 {
  132         struct veriexec_fp_ops *ops = NULL;
  133 
  134         LIST_INIT(&veriexec_ops_list);
  135 
  136 #ifdef VERIFIED_EXEC_FP_RMD160
  137         ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
  138         VERIEXEC_OPINIT(ops, "RMD160", RMD160_DIGEST_LENGTH,
  139                         sizeof(RMD160_CTX), RMD160Init, RMD160Update,
  140                         RMD160Final);
  141         (void) veriexec_add_fp_ops(ops);
  142 #endif /* VERIFIED_EXEC_FP_RMD160 */
  143 
  144 #ifdef VERIFIED_EXEC_FP_SHA256
  145         ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
  146         VERIEXEC_OPINIT(ops, "SHA256", SHA256_DIGEST_LENGTH,
  147                         sizeof(SHA256_CTX), SHA256_Init, SHA256_Update,
  148                         SHA256_Final);
  149         (void) veriexec_add_fp_ops(ops);
  150 #endif /* VERIFIED_EXEC_FP_SHA256 */
  151 
  152 #ifdef VERIFIED_EXEC_FP_SHA384
  153         ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
  154         VERIEXEC_OPINIT(ops, "SHA384", SHA384_DIGEST_LENGTH,
  155                         sizeof(SHA384_CTX), SHA384_Init, SHA384_Update,
  156                         SHA384_Final);
  157         (void) veriexec_add_fp_ops(ops);
  158 #endif /* VERIFIED_EXEC_FP_SHA384 */
  159 
  160 #ifdef VERIFIED_EXEC_FP_SHA512
  161         ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
  162         VERIEXEC_OPINIT(ops, "SHA512", SHA512_DIGEST_LENGTH,
  163                         sizeof(SHA512_CTX), SHA512_Init, SHA512_Update,
  164                         SHA512_Final);
  165         (void) veriexec_add_fp_ops(ops);
  166 #endif /* VERIFIED_EXEC_FP_SHA512 */
  167 
  168 #ifdef VERIFIED_EXEC_FP_SHA1
  169         ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
  170         VERIEXEC_OPINIT(ops, "SHA1", SHA1_DIGEST_LENGTH,
  171                         sizeof(SHA1_CTX), SHA1Init, SHA1Update,
  172                         SHA1Final);
  173         (void) veriexec_add_fp_ops(ops);
  174 #endif /* VERIFIED_EXEC_FP_SHA1 */
  175 
  176 #ifdef VERIFIED_EXEC_FP_MD5
  177         ops = (struct veriexec_fp_ops *) malloc(sizeof(*ops), M_TEMP, M_WAITOK);
  178         VERIEXEC_OPINIT(ops, "MD5", MD5_DIGEST_LENGTH, sizeof(MD5_CTX),
  179                         MD5Init, MD5Update, MD5Final);
  180         (void) veriexec_add_fp_ops(ops);
  181 #endif /* VERIFIED_EXEC_FP_MD5 */
  182 }
  183 
  184 struct veriexec_fp_ops *
  185 veriexec_find_ops(u_char *name)
  186 {
  187         struct veriexec_fp_ops *ops;
  188 
  189         name[VERIEXEC_TYPE_MAXLEN] = '\0';
  190 
  191         LIST_FOREACH(ops, &veriexec_ops_list, entries) {
  192                 if ((strlen(name) == strlen(ops->type)) &&
  193                     (strncasecmp(name, ops->type, sizeof(ops->type) - 1)
  194                      == 0))
  195                         return (ops);
  196         }
  197 
  198         return (NULL);
  199 }
  200 
  201 /*
  202  * Calculate fingerprint. Information on hash length and routines used is
  203  * extracted from veriexec_hash_list according to the hash type.
  204  */
  205 int
  206 veriexec_fp_calc(struct proc *p, struct vnode *vp,
  207                  struct veriexec_hash_entry *vhe, uint64_t size, u_char *fp)
  208 {
  209         void *ctx = NULL;
  210         u_char *buf = NULL;
  211         off_t offset, len;
  212         size_t resid;
  213         int error = 0;
  214 
  215         /* XXX: This should not happen. Print more details? */
  216         if (vhe->ops == NULL) {
  217                 panic("veriexec: Operations vector is NULL");
  218         }
  219 
  220         memset(fp, 0, vhe->ops->hash_len);
  221 
  222         ctx = (void *) malloc(vhe->ops->context_size, M_TEMP, M_WAITOK);
  223         buf = (u_char *) malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
  224 
  225         (vhe->ops->init)(ctx); /* init the fingerprint context */
  226 
  227         /*
  228          * The vnode is locked. sys_execve() does it for us; We have our
  229          * own locking in vn_open().
  230          */
  231         for (offset = 0; offset < size; offset += PAGE_SIZE) {
  232                 len = ((size - offset) < PAGE_SIZE) ? (size - offset)
  233                         : PAGE_SIZE;
  234 
  235                 error = vn_rdwr(UIO_READ, vp, buf, len, offset,
  236                                 UIO_SYSSPACE,
  237 #ifdef __FreeBSD__
  238                                 IO_NODELOCKED,
  239 #else
  240                                 0,
  241 #endif
  242                                 p->p_ucred, &resid, NULL);
  243 
  244                 if (error)
  245                         goto bad;
  246 
  247                 /* calculate fingerprint for each chunk */
  248                 (vhe->ops->update)(ctx, buf, (unsigned int) len);
  249         }
  250 
  251         /* finalise the fingerprint calculation */
  252         (vhe->ops->final)(fp, ctx);
  253 
  254 bad:
  255         free(ctx, M_TEMP);
  256         free(buf, M_TEMP);
  257 
  258         return (error);
  259 }
  260 
  261 /* Compare two fingerprints of the same type. */
  262 int
  263 veriexec_fp_cmp(struct veriexec_fp_ops *ops, u_char *fp1, u_char *fp2)
  264 {
  265         if (veriexec_verbose >= 2) {
  266                 int i;
  267 
  268                 printf("comparing hashes...\n");
  269                 printf("fp1: ");
  270                 for (i = 0; i < ops->hash_len; i++) {
  271                         printf("%x", fp1[i]);
  272                 }
  273                 printf("\nfp2: ");
  274                 for (i = 0; i < ops->hash_len; i++) {
  275                         printf("%x", fp2[i]);
  276                 }
  277                 printf("\n");
  278         }
  279 
  280         return (memcmp(fp1, fp2, ops->hash_len));
  281 }
  282 
  283 /* Get the hash table for the specified device. */
  284 struct veriexec_hashtbl *
  285 veriexec_tblfind(dev_t device) {
  286         struct veriexec_hashtbl *tbl;
  287 
  288         LIST_FOREACH(tbl, &veriexec_tables, hash_list) {
  289                 if (tbl->hash_dev == device)
  290                         return (tbl);
  291         }
  292 
  293         return (NULL);
  294 }
  295 
  296 /* Perform a lookup on a hash table. */
  297 struct veriexec_hash_entry *
  298 veriexec_lookup(dev_t device, ino_t inode)
  299 {
  300         struct veriexec_hashtbl *tbl;
  301         struct veriexec_hashhead *tble;
  302         struct veriexec_hash_entry *e;
  303         size_t indx;
  304 
  305         tbl = veriexec_tblfind(device);
  306         if (tbl == NULL)
  307                 return (NULL);
  308 
  309         indx = VERIEXEC_HASH(tbl, inode);
  310         tble = &(tbl->hash_tbl[indx & VERIEXEC_HASH_MASK(tbl)]);
  311 
  312         LIST_FOREACH(e, tble, entries) {
  313                 if ((e != NULL) && (e->inode == inode))
  314                         return (e);
  315         }
  316 
  317         return (NULL);
  318 }
  319 
  320 /*
  321  * Add an entry to a hash table. If a collision is found, handle it.
  322  * The passed entry is allocated in kernel memory.
  323  */
  324 int
  325 veriexec_hashadd(struct veriexec_hashtbl *tbl, struct veriexec_hash_entry *e)
  326 {
  327         struct veriexec_hashhead *vhh;
  328         size_t indx;
  329 
  330         if (tbl == NULL)
  331                 return (EFAULT);
  332 
  333         indx = VERIEXEC_HASH(tbl, e->inode);
  334         vhh = &(tbl->hash_tbl[indx]);
  335 
  336         if (vhh == NULL)
  337                 panic("veriexec: veriexec_hashadd: vhh is NULL.");
  338 
  339         LIST_INSERT_HEAD(vhh, e, entries);
  340 
  341         tbl->hash_count++;
  342 
  343         return (0);
  344 }
  345 
  346 /*
  347  * Verify the fingerprint of the given file. If we're called directly from
  348  * sys_execve(), 'flag' will be VERIEXEC_DIRECT. If we're called from
  349  * exec_script(), 'flag' will be VERIEXEC_INDIRECT.  If we are called from
  350  * vn_open(), 'flag' will be VERIEXEC_FILE.
  351  */
  352 int
  353 veriexec_verify(struct proc *p, struct vnode *vp, struct vattr *va,
  354                 const u_char *name, int flag, struct veriexec_hash_entry **ret)
  355 {
  356         struct veriexec_hash_entry *vhe = NULL;
  357         u_char *digest = NULL;
  358         int error = 0;
  359 
  360         if (vp->v_type != VREG)
  361                 return (0);
  362 
  363         /* Lookup veriexec table entry, save pointer if requested. */
  364         /*
  365          * XXX: Both va_fsid and va_fileid are long (32/64 bits), while
  366          * XXX: veriexec_lookup() is passed dev_t and ino_t - uint32_t.
  367          */
  368         vhe = veriexec_lookup((dev_t)va->va_fsid, (ino_t)va->va_fileid);
  369         if (ret != NULL)
  370                 *ret = vhe;
  371         if (vhe == NULL)
  372                 goto out;
  373 
  374         /* Evaluate fingerprint if needed. */
  375         if (vhe->status == FINGERPRINT_NOTEVAL) {
  376                 /* Calculate fingerprint for on-disk file. */
  377                 digest = (u_char *) malloc(vhe->ops->hash_len, M_TEMP,
  378                                            M_WAITOK);
  379                 error = veriexec_fp_calc(p, vp, vhe, va->va_size, digest);
  380                 if (error) {
  381                         veriexec_report("Fingerprint calculation error.",
  382                                         name, va, NULL, REPORT_NOVERBOSE,
  383                                         REPORT_NOALARM, REPORT_NOPANIC);
  384                         free(digest, M_TEMP);
  385                         return (error);
  386                 }
  387 
  388                 /* Compare fingerprint with loaded data. */
  389                 if (veriexec_fp_cmp(vhe->ops, vhe->fp, digest) == 0) {
  390                         vhe->status = FINGERPRINT_VALID;
  391                 } else {
  392                         vhe->status = FINGERPRINT_NOMATCH;
  393                 }
  394 
  395                 free(digest, M_TEMP);
  396         }
  397 
  398         if (!(vhe->type & flag)) {
  399                 veriexec_report("Incorrect access type.", name, va, p,
  400                                 REPORT_NOVERBOSE, REPORT_ALARM,
  401                                 REPORT_NOPANIC);
  402 
  403                 /* IPS mode: Enforce access type. */
  404                 if (veriexec_strict >= 2)
  405                         return (EPERM);
  406         }
  407 
  408 out:
  409         /* No entry in the veriexec tables. */
  410         if (vhe == NULL) {
  411                 veriexec_report("veriexec_verify: No entry.", name, va,
  412                     p, REPORT_VERBOSE, REPORT_NOALARM, REPORT_NOPANIC);
  413 
  414                 /* Lockdown mode: Deny access to non-monitored files if
  415                  * strict is 3 or higher, make an exception for executables
  416                  * since we don't want to run an unverified binary at strict
  417                  * 2 or higher.
  418                  */
  419                 if ((veriexec_strict >= 3) ||
  420                     ((veriexec_strict >= 2) && (flag != VERIEXEC_FILE)))
  421                         return (EPERM);
  422 
  423                 return (0);
  424         }
  425 
  426         switch (vhe->status) {
  427         case FINGERPRINT_NOTEVAL:
  428                 /* Should not happen. */
  429                 veriexec_report("veriexec_verify: Not-evaluated status "
  430                     "post evaluation; inconsistency detected.", name, va,
  431                     NULL, REPORT_NOVERBOSE, REPORT_NOALARM, REPORT_PANIC);
  432 
  433         case FINGERPRINT_VALID:
  434                 /* Valid fingerprint. */
  435                 veriexec_report("veriexec_verify: Match.", name, va, NULL,
  436                     REPORT_VERBOSE, REPORT_NOALARM, REPORT_NOPANIC);
  437 
  438                 break;
  439 
  440         case FINGERPRINT_NOMATCH:
  441                 /* Fingerprint mismatch. */
  442                 veriexec_report("veriexec_verify: Mismatch.", name, va,
  443                     NULL, REPORT_NOVERBOSE, REPORT_ALARM, REPORT_NOPANIC);
  444 
  445                 /* IDS mode: Deny access on fingerprint mismatch. */
  446                 if (veriexec_strict >= 1)
  447                         error = EPERM;
  448 
  449                 break;
  450 
  451         default:
  452                 /*
  453                  * Should never happen.
  454                  * XXX: Print vnode/process?
  455                  */
  456                 veriexec_report("veriexec_verify: Invalid stats "
  457                     "post evaluation.", name, va, NULL, REPORT_NOVERBOSE,
  458                     REPORT_NOALARM, REPORT_PANIC);
  459         }
  460 
  461         return (error);
  462 }
  463 
  464 /*
  465  * Veriexec remove policy code.
  466  */
  467 int
  468 veriexec_removechk(struct proc *p, struct vnode *vp, const char *pathbuf)
  469 {
  470         struct veriexec_hashtbl *tbl;
  471         struct veriexec_hash_entry *vhe = NULL;
  472         struct vattr va;
  473         int error;
  474 
  475         error = VOP_GETATTR(vp, &va, p->p_ucred, p);
  476         if (error)
  477                 return (error);
  478 
  479         vhe = veriexec_lookup(va.va_fsid, va.va_fileid);
  480         if (vhe == NULL) {
  481                 /* Lockdown mode: Deny access to non-monitored files. */
  482                 if (veriexec_strict >= 3)
  483                         return (EPERM);
  484 
  485                 return (0);
  486         }
  487 
  488         veriexec_report("Remove request.", pathbuf, &va, p,
  489                         REPORT_NOVERBOSE, REPORT_ALARM, REPORT_NOPANIC);
  490 
  491         /* IPS mode: Deny removal of monitored files. */
  492         if (veriexec_strict >= 2)
  493                 return (EPERM);
  494 
  495         tbl = veriexec_tblfind(va.va_fsid);
  496         if (tbl == NULL) {
  497                 veriexec_report("veriexec_removechk: Inconsistency "
  498                     "detected: Could not get table for file in lists.",
  499                     pathbuf, &va, NULL, REPORT_NOVERBOSE, REPORT_NOALARM,
  500                     REPORT_PANIC);
  501         }
  502 
  503         LIST_REMOVE(vhe, entries);
  504         if (vhe->fp != NULL)
  505                 free(vhe->fp, M_TEMP);
  506         free(vhe, M_TEMP);
  507         tbl->hash_count--;
  508 
  509         return (error);
  510 }
  511 
  512 /*
  513  * Veriexe rename policy.
  514  */
  515 int
  516 veriexec_renamechk(struct vnode *vp, struct vnode *tvp, const char *from,
  517                    const char *to)
  518 {
  519         struct proc *p = curlwp->l_proc;
  520         struct veriexec_hash_entry *vhe, *tvhe;
  521         struct vattr va, tva;
  522         int error;
  523 
  524         error = VOP_GETATTR(vp, &va, p->p_ucred, p);
  525         if (error)
  526                 return (error);
  527 
  528         if (veriexec_strict >= 3) {
  529                 printf("Veriexec: veriexec_renamechk: Preventing rename "
  530                        "of \"%s\" [%ld:%llu] to \"%s\", uid=%u, pid=%u: "
  531                        "Lockdown mode.\n", from, va.va_fsid,
  532                        (unsigned long long)va.va_fileid,
  533                        to, p->p_ucred->cr_uid, p->p_pid);
  534                 return (EPERM);
  535         }
  536 
  537         /* XXX: dev_t and ino_t are 32bit, long can be 64bit. */
  538         vhe = veriexec_lookup((dev_t)va.va_fsid, (ino_t)va.va_fileid);
  539 
  540         if (tvp != NULL) {
  541                 error = VOP_GETATTR(tvp, &tva, p->p_ucred, p);
  542                 if (error)
  543                         return (error);
  544                 tvhe = veriexec_lookup((dev_t)tva.va_fsid,
  545                                        (ino_t)tva.va_fileid);
  546         } else
  547                 tvhe = NULL;
  548 
  549         if ((vhe != NULL) || (tvhe != NULL)) {
  550                 if (veriexec_strict >= 2) {
  551                         printf("Veriexec: veriexec_renamechk: Preventing "
  552                                "rename of \"%s\" [%ld:%llu] to \"%s\", "
  553                                "uid=%u, pid=%u: IPS mode, file "
  554                                "monitored.\n", from, va.va_fsid,
  555                                (unsigned long long)va.va_fileid,
  556                                to, p->p_ucred->cr_uid, p->p_pid);
  557                         return (EPERM);
  558                 }
  559 
  560                 printf("Veriexec: veriexec_rename: Monitored file \"%s\" "
  561                        "[%ld:%llu] renamed to \"%s\", uid=%u, pid=%u.\n",
  562                        from, va.va_fsid, (unsigned long long)va.va_fileid, to,
  563                        p->p_ucred->cr_uid, p->p_pid);
  564         }
  565 
  566         return (0);
  567 }
  568 
  569 /*
  570  * Routine for maintaining mostly consistent message formats in Verified
  571  * Exec.
  572  *
  573  * 'verbose_only' - if 1, the message will be printed only if veriexec is
  574  * in verbose mode.
  575  * 'alarm' - if 1, the message is considered an alarm and will be printed
  576  * at all times along with pid and user credentials.
  577  * 'die' - if 1, the system will call panic() instead of printf().
  578  */
  579 void
  580 veriexec_report(const u_char *msg, const u_char *filename,
  581                 struct vattr *va, struct proc *p, int verbose, int alarm,
  582                 int die)
  583 {
  584         void (*f)(const char *, ...);
  585 
  586         if (msg == NULL || filename == NULL || va == NULL)
  587                 return;
  588 
  589         if (die)
  590                 f = panic;
  591         else
  592                 f = (void (*)(const char *, ...)) printf;
  593 
  594         if (!verbose || (verbose == veriexec_verbose)) {
  595                 if (!alarm || p == NULL)
  596                         f("veriexec: %s [%s, %ld:%ld%s", msg, filename,
  597                             va->va_fsid, va->va_fileid,
  598                             die ? "]" : "]\n");
  599                 else
  600                         f("veriexec: %s [%s, %ld:%ld, pid=%u, uid=%u, "
  601                             "gid=%u%s", msg, filename, va->va_fsid,
  602                             va->va_fileid, p->p_pid, p->p_cred->p_ruid,
  603                             p->p_cred->p_rgid, die ? "]" : "]\n");
  604         }
  605 }

Cache object: 7fda958f1c4e3ee17b71e9720172aa69


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.