VERIEXEC(9) | Kernel Developer's Manual | VERIEXEC(9)

# NAME

`veriexec` —
in-kernel file integrity subsystem KPI

# SYNOPSIS

`#include <sys/verified_exec.h>`

void
`veriexec_init`(void);

bool
`veriexec_lookup`(struct vnode *vp);

int
`veriexec_verify`(struct lwp *l, struct vnode *vp, const u_char *name, int flag, bool *found);

void
`veriexec_purge`(struct vnode *vp);

int
`veriexec_fpops_add`(const char *fp_type, size_t hash_len, size_t ctx_size, veriexec_fpop_init_t init, veriexec_fpop_update_t update, veriexec_fpop_final_t final);

int
`veriexec_file_add`(struct lwp *l, prop_dictionary_t dict);

int
`veriexec_file_delete`(struct lwp *l, struct vnode *vp);

int
`veriexec_table_delete`(struct lwp *l, struct mount *mp);

int
`veriexec_flush`(struct lwp *l);

int
`veriexec_openchk`(struct lwp *l, struct vnode *vp, const char *path, int fmode);

int
`veriexec_renamechk`(struct lwp *l, struct vnode *fromvp, const char *fromname, struct vnode *tovp, const char *toname);

int
`veriexec_removechk`(struct lwp *l, struct vnode *vp, const char *name);

int
`veriexec_unmountchk`(struct mount *mp);

int
`veriexec_convert`(struct vnode *vp, prop_dictionary_t rdict);

int
`veriexec_dump`(struct lwp *l, prop_array_t rarray);

# DESCRIPTION

`veriexec` is the KPI for Veriexec, the NetBSD in-kernel file integrity subsystem. It is responsible for managing the supported hashing algorithms, fingerprint calculation and comparison, file monitoring tables, and relevant hooks to enforce the Veriexec policy.

# FUNCTIONS

## Core Routines

`veriexec_init`(void)
  Initialize the Veriexec subsystem. Called only once during system startup.
`veriexec_lookup`(vp)
  Check if vp is monitored by Veriexec. Returns `true` if it is, or `false` otherwise.
`veriexec_verify`(l, vp, name, flag, found)
  Verifies the digital fingerprint of vp. name is the filename, and flag is the access flag. The access flag can be one of:
  `VERIEXEC_DIRECT`
    The file was executed directly via execve(2).
  `VERIEXEC_INDIRECT`
    The file was executed indirectly, either as an interpreter for a script or mapped to an executable memory region.
  `VERIEXEC_FILE`
    The file was opened for reading/writing.

  l is the LWP for the request context.

  An optional argument, found, is a pointer to a boolean indicating whether an entry for the file was found in the Veriexec tables.

`veriexec_purge`(vp)
  Purge the file entry for vp. This invalidates the fingerprint so it will be evaluated next time the file is accessed.

## Fingerprint Related Routines

`veriexec_fpops_add`(fp_type, hash_len, ctx_size, init, update, final)
  Add support for fingerprinting algorithm fp_type with binary hash length hash_len and calculation context size ctx_size to Veriexec. init, update, and final are the routines used to initialize, update, and finalize a calculation context.

## Table Management Routines

`veriexec_file_add`(l, dict)
  Add a Veriexec entry for the file described by dict.

  dict is expected to have the following:

  Name | Type | Purpose
  file | string | filename
  entry-type | uint8 | entry type flags (see veriexec(4))
  fp-type | string | fingerprint hashing algorithm
  fp | data | the fingerprint

`veriexec_file_delete`(l, vp)
  Remove Veriexec entry for vp.
`veriexec_table_delete`(l, mp)
  Remove Veriexec table for mount-point mp.
`veriexec_flush`(l)
  Delete all Veriexec tables.

## Hook Handlers

`veriexec_openchk`(l, vp, path, fmode)
  Called when a file is opened.

  l is the LWP opening the file, vp is a vnode for the file being opened as returned from namei(9). If `NULL`, the file is being created. path is the pathname for the file (not necessarily a full path), and fmode are the mode bits with which the file was opened.

`veriexec_renamechk`(l, fromvp, fromname, tovp, toname)
  Called when a file is renamed.

  fromvp and fromname are the vnode and filename of the file being renamed. tovp and toname are the vnode and filename of the target file. l is the LWP renaming the file.

  Depending on the strict level, `veriexec` will either track changes appropriately or prevent the rename.

`veriexec_removechk`(l, vp, name)
  Called when a file is removed.

  vp is the vnode of the file being removed, and name is the filename. l is the LWP removing the file,

  Depending on the strict level, `veriexec` will either clean-up after the file or prevent its removal.

`veriexec_unmountchk`(mp)
  Checks if the current strict level allows mp to be unmounted.

## Miscellaneous Routines

`veriexec_convert`(vp, rdict)
  Convert Veriexec entry for vp to human-readable proplib(3) dictionary, rdict, with the following elements:

  Name | Type | Purpose
  entry-type | uint8 | entry type flags (see veriexec(4))
  status | uint8 | entry status (see below)
  fp-type | string | fingerprint hashing algorithm
  fp | data | the fingerprint

  The “status” can be one of the following:

  Status | Meaning
  FINGERPRINT_NOTEVAL | not evaluated
  FINGERPRINT_VALID | fingerprint match
  FINGERPRINT_MISMATCH | fingerprint mismatch

  If no entry was found, `ENOENT` is returned. Otherwise, zero.

`veriexec_dump`(l, rarray)
  Fill rarray with entries for all files monitored by Veriexec that have a filename associated with them.

  Each element in rarray is a dictionary with the same elements as filled by `veriexec_convert`(), with an additional field, “file”, containing the filename.

# FILES

Path | Purpose
src/sys/dev/veriexec.c | driver for userland communication
src/sys/sys/verified_exec.h | shared (userland/kernel) header file
src/sys/kern/kern_veriexec.c | subsystem code
src/sys/kern/vfs_syscalls.c | rename, remove, and unmount policies
src/sys/kern/vfs_vnops.c | regular file access policy

# SEE ALSO

proplib(3), sysctl(3), veriexec(4), security(7), sysctl(8), veriexecctl(8), veriexecgen(8), fileassoc(9)

# AUTHORS

Brett Lymn <blymn@NetBSD.org>
Elad Efrat <elad@NetBSD.org>

# CAVEATS

There are two known issues with Veriexec that should be considered when using it.

## Remote File-systems

There is an issue providing protection for files residing on mounts from remote hosts. Because access to the file-system does not necessarily go through `veriexec`, there is no way to track on-disk changes. While it is possible to minimize the effect by evaluating the file's fingerprint on each access without caching the result, a problem arises when a file is overwritten after its fingerprint has been evaluated and it is running on the local host.

An attacker could potentially overwrite the file contents in the remote host at that point, and force a flush on the local host, resulting in paging in of the files from the disk, introducing malicious code into a supposedly safe address space.

There is a fix for this issue, however due to dependencies on other work that is still in progress it has not been committed yet.

## Layered File-systems

Due to VFS limitations, `veriexec` cannot track the same on-disk file across multiple layers of overlay file-systems. Therefore, you cannot expect changes to files on overlay mounts will be detected simply because the underlying mount is monitored by `veriexec`.

A workaround for this issue is listing all files, under all mounts, you want monitored in the signature file.

December 9, 2015 | NetBSD 9.2