
Integrity and IMA Modules for CentOS 7 (Linux version 3.10)
===============================================================================

===============================================================================

Kam Nasim <kam.nasim@windriver.com>
Copyright (c) 2017 Wind River Systems, Inc.

SPDX-License-Identifier: Apache-2.0


August, 2017

===============================================================================

Contents
--------

- Overview
- Rebasing Guidelines
- Changesets

================================================================================


Important Notes
---------------

No support for APPENDING IMA policies
----------------------------------------------

A provision was introduced in April 2014 to allow multiple IMA policies to be
appended.This change involved setting up inode hooks which could not be
backported in the 3.10 Kernel. Therefore we do not allow the following operation
types:
echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy

only an overwrite is possible:
cat policy-file > <securityfs>/ima/policy

EVM support disabled in Kernel
------------------------------------------------

The EVM Kernel Configuration option was mutually exclusive to the CONFIG_INTEGRITY
Kernel configuration option. Since Integrity is being disabled in the Kernel, EVM
would also need to be built out-of-tree as a Kernel module and would require some
refactoring if it is to be used with this module pack.


IMA Keyring allocated inside the Kernel
-----------------------------------------

Normally, the _ima Keyring is allocated from user space, but this has the 
added disadvantage of persisting the public key on the file system. Corruption
of this public key may cripple the system by triggering APPRAISAL failures if
ima 'Enforcement' is enabled. To prevent this, the IMA public key is compiled
into the Kernel and is placed in the Kernel SOURCE (ima_signing_key.pub)


Overview
--------

This module pack builds Integrity and IMA kernel modules for the 3.10 kernel version.
If newer kernel version are to be supported in the future then the COMPAT
layer (kcompat.h) will need to be adjusted to address kernel-driver compatibility
issues. As well as certain LINUX_VERSION_CODE <= KERNEL_VERSION(3,10,0) ifdefs 

It supports Linux supported x86_64 systems.

These drivers are only supported as a loadable module at this time.


Rebasing Guidelines
--------------------

On rebasing TiC software heed the following:
- always rebase the Kernel first before rebasing this package
- get the HEAD from the tpmdd repo and generate a tarball, the tarball
should follow the naming convention: tpm-kmod-<gitHEAD>; use the short-hand
form of the git commit ID (8 characters)
- update the integrity-kmod spec to Source the new tarball
- apply all existing patches against the new tarball, and adjust the kcompat
layer (LINUX_VERSION_CODE ifdefs, kcompat.h and common.mk) accordingly

IMA Signing Key Generation Guidelines
--------------------------------------

The following may be used to generate an IMA key pair:
openssl req -newkey rsa:2048 -nodes -days 10950 -x509 -outform DER -out ima_signing_key.pub -keyout ima_signing_key.priv

The "ima_signing_key.pub" MUST be placed in the Kernel source (files/) so that the 
Kernel build can pick it up and compile it in.


================================================================================


Change Sets
-------------------------

This driver is a fork from the tpmdd repo:
https://sourceforge.net/projects/tpmdd/
http://git.infradead.org/users/jjs/linux-tpmdd.git/

Sync Head: 668a827057187403999b7ecfcf86b59979c8c3b2

COMPAT NOTES:

1. In newer kernels, VFS layer read operations have been refactored:
    VFS: refactor vfs_read()

    integrity_kernel_read() duplicates the file read operations code
    in vfs_read(). This patch refactors vfs_read() code creating a
    helper function __vfs_read(). It is used by both vfs_read() and
    integrity_kernel_read().

    Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
    Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

   The compat layer therefore needs to redefine the integrity vfs code to use
   the original implementation


2. In newer kernels, a wrapper has been developed around inode mutex un/lock
   
        commit 5955102c9984fa081b2d570cfac75c97eecf8f3b
        Author: Al Viro <viro@zeniv.linux.org.uk>
        Date:   Fri Jan 22 15:40:57 2016 -0500

        wrappers for ->i_mutex access

        parallel to mutex_{lock,unlock,trylock,is_locked,lock_nested},
        inode_foo(inode) being mutex_foo(&inode->i_mutex).

        Please, use those for access to ->i_mutex; over the coming cycle
        ->i_mutex will become rwsem, with ->lookup() done with it held
        only shared.

        Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

    The compat layer needs to replace all instances of inode locking
    with the underlying mutex locking/unlocking calls    


3. In newer kernels, security PRE and POST Hooks are defined which 
have their seperate appraisal calls

    commit 39eeb4fb97f60dbdfc823c1a673a8844b9226b60
    Author: Mimi Zohar <zohar@linux.vnet.ibm.com>
    Date:   Sat Jan 30 22:23:26 2016 -0500

    security: define kernel_read_file hook

    The kernel_read_file security hook is called prior to reading the file
    into memory.

    Changelog v4+:
    - export security_kernel_read_file()

    Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
    Acked-by: Kees Cook <keescook@chromium.org>
    Acked-by: Luis R. Rodriguez <mcgrof@kernel.org>
    Acked-by: Casey Schaufler <casey@schaufler-ca.com>
        
   The compat layer needs to ignore all PRE and POST File hooks and 
   cannot support such PRE and POST appraisals


4. In newer kernels, IMA policies can be applied by path as opposed to
content allowing multiple policies to be appended

    commit 7429b092811fb20c6a5b261c2c116a6a90cb9a29
Author: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Date:   Fri Apr 11 17:47:01 2014 +0300

    ima: load policy using path

    We currently cannot do appraisal or signature vetting of IMA policies
    since we currently can only load IMA policies by writing the contents
    of the policy directly in, as follows:

    cat policy-file > <securityfs>/ima/policy

    If we provide the kernel the path to the IMA policy so it can load
    the policy itself it'd be able to later appraise or vet the file
    signature if it has one.  This patch adds support to load the IMA
    policy with a given path as follows:

    echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy

    Changelog v4+:
    - moved kernel_read_file_from_path() error messages to callers
    v3:
    - moved kernel_read_file_from_path() to a separate patch
    v2:
    - after re-ordering the patches, replace calling integrity_kernel_read()
      to read the file with kernel_read_file_from_path() (Mimi)
    - Patch description re-written by Luis R. Rodriguez

    Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>

    This feature was removed from the IMA modules since it required extensive
backporting to the INODE and VFS layers inthe base kernel

5. In newer kernels, IMA allows measurement lists to be preserved over
Kernel reinstalls or kexecs

    commit d9ddf077bb85b54200dfcb5f2edec4f0d6a7c2ca
Author: Mimi Zohar <zohar@linux.vnet.ibm.com>
Date:   Thu Jan 14 20:59:14 2016 -0500

    ima: support for kexec image and initramfs

    Add IMA policy support for measuring/appraising the kexec image and
    initramfs. Two new IMA policy identifiers KEXEC_KERNEL_CHECK and
    KEXEC_INITRAMFS_CHECK are defined.

    Example policy rules:
    measure func=KEXEC_KERNEL_CHECK
    appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
    measure func=KEXEC_INITRAMFS_CHECK
    appraise func=KEXEC_INITRAMFS_CHECK appraise_type=imasig

    Moving the enumeration to the vfs layer simplified the patches, allowing
    the IMA changes, for the most part, to be separated from the other
    changes.  Unfortunately, passing either a kernel_read_file_id or a
    ima_hooks enumeration within IMA is messy.

    This feature was removed from the IMA modules since it required defining a
new Kexec cache in the base Kernel which was an extensive backporting effort
