mbox series

[RFC,0/9] integrity: Introduce DIGLIM advanced features

Message ID 20210915163145.1046505-1-roberto.sassu@huawei.com (mailing list archive)
Headers show
Series integrity: Introduce DIGLIM advanced features | expand

Message

Roberto Sassu Sept. 15, 2021, 4:31 p.m. UTC
Introduction
============

This patch set depends on:
- support for the euid policy keyword for critical data
  (https://lore.kernel.org/linux-integrity/20210705115650.3373599-1-roberto.sassu@huawei.com/)
- basic DIGLIM
  (https://lore.kernel.org/linux-integrity/20210914163401.864635-1-roberto.sassu@huawei.com/)

Introduce the remaining features necessary to upload to the kernel
reference values from RPM headers or digest lists in other formats.

Loader: it will automatically uploads digest lists from a directory
        specified in the kernel configuration and will execute a user space
        uploader to upload digest lists in a format that is not recognized
        by the kernel;

LSM: it identifies digest list parsers and monitor their activity for
     integrity evaluation; it protects digest list parsers from other user
     space processes considered as untrusted;

Digest list generators: user space tools to generate digest lists from
                        files (in the compact format) or from the RPM DB;

Digest list uploader and parsers: user space tools responsible to upload to
                                  the kernel digest lists not in the
                                  compact format (e.g. those derived from
                                  the RPM DB);

Administration guide: it describes the steps necessary to upload to the
                      kernel all the digests of an RPM-based Linux
                      distribution, using a custom kernel with the DIGLIM
                      patches applied.

With these changes, DIGLIM is ready to be used by IMA for measurement and
appraisal (this functionality will be added with a future patch set).

DIGLIM already supports appended signatures, but at the moment they cannot
be interpreted by IMA (unsupported ID PKEY_ID_PGP). Another patch set is
necessary to load the PGP keys from the Linux distribution to the system
keyring and to verify the PGP signatures of the RPM headers.

With the patch sets above and the execution policies for IMA proposed some
time ago, it will be possible to generate a measurement list with digest
lists and unknown files, and enable IMA appraisal in enforcing mode.
The kernel command line would be:

ima_template=ima-modsig ima_policy="exec_tcb|tmpfs|digest_lists|appraise_exec_tcb|appraise_tmpfs|appraise_digest_lists"

The effort required for Linux distribution vendors will be to generate and
sign the digest lists for the digest list uploader and the RPM parser. This
could be done for example in the kernel-tools package (or in a separate
package). Existing package signatures are sufficient for remaining files.


Issues/Questions
================

Lockdep (patch 2/9)
-------------------

I'm using iterate_dir() and file_open_root() to iterate and open files
in a directory. Unfortunately, I get the following warning:

============================================
WARNING: possible recursive locking detected
5.15.0-rc1-dont-use-00049-ga5a881519991 #134 Not tainted
--------------------------------------------
swapper/1 is trying to acquire lock:
0000000066812898 (&sb->s_type->i_mutex_key#7){++++}-{4:4}, at: path_openat+0x75d/0xd20

but task is already holding lock:
0000000066812898 (&sb->s_type->i_mutex_key#7){++++}-{4:4}, at: iterate_dir+0x65/0x250

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&sb->s_type->i_mutex_key#7);
  lock(&sb->s_type->i_mutex_key#7);

 *** DEADLOCK ***


due to the fact that path_openat() might be trying to lock the directory
already locked by iterate_dir(). What it would be a good way to avoid it?


Inode availability in security_file_free() (patch 3/9)
------------------------------------------------------

It seems that this hook is called when the last reference to a file is
released. After enabling debugging, sometimes the kernel reported that the
inode I was trying to access was already freed.

To avoid this situation, I'm grabbing an additional reference of the inode
in the security_file_open() hook, to ensure that the inode does not
disappear, and I'm releasing it in the security_file_free() hook. Is this
solution acceptable?

Roberto Sassu (9):
  ima: Introduce new hook DIGEST_LIST_CHECK
  diglim: Loader
  diglim: LSM
  diglim: Tests - LSM
  diglim: Compact digest list generator
  diglim: RPM digest list generator
  diglim: Digest list uploader
  diglim: RPM parser
  diglim: Admin guide

 Documentation/admin-guide/diglim.rst          | 136 +++++
 Documentation/admin-guide/index.rst           |   1 +
 .../security/diglim/implementation.rst        |  16 +
 Documentation/security/diglim/index.rst       |   1 +
 Documentation/security/diglim/lsm.rst         |  65 +++
 Documentation/security/diglim/tests.rst       |  18 +-
 MAINTAINERS                                   |  10 +
 security/integrity/diglim/Kconfig             |  14 +
 security/integrity/diglim/Makefile            |   2 +-
 security/integrity/diglim/diglim.h            |  27 +
 security/integrity/diglim/fs.c                |   3 +
 security/integrity/diglim/hooks.c             | 436 ++++++++++++++++
 security/integrity/diglim/loader.c            |  92 ++++
 security/integrity/iint.c                     |   1 +
 security/integrity/ima/ima.h                  |   1 +
 security/integrity/ima/ima_main.c             |   3 +-
 security/integrity/ima/ima_policy.c           |   3 +
 security/integrity/integrity.h                |   8 +
 tools/diglim/Makefile                         |  27 +
 tools/diglim/common.c                         |  79 +++
 tools/diglim/common.h                         |  59 +++
 tools/diglim/compact_gen.c                    | 349 +++++++++++++
 tools/diglim/rpm_gen.c                        | 334 ++++++++++++
 tools/diglim/rpm_parser.c                     | 483 ++++++++++++++++++
 tools/diglim/upload_digest_lists.c            | 238 +++++++++
 tools/testing/selftests/diglim/Makefile       |  12 +-
 tools/testing/selftests/diglim/common.h       |   9 +
 tools/testing/selftests/diglim/selftest.c     | 357 ++++++++++++-
 28 files changed, 2764 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/admin-guide/diglim.rst
 create mode 100644 Documentation/security/diglim/lsm.rst
 create mode 100644 security/integrity/diglim/hooks.c
 create mode 100644 security/integrity/diglim/loader.c
 create mode 100644 tools/diglim/Makefile
 create mode 100644 tools/diglim/common.c
 create mode 100644 tools/diglim/common.h
 create mode 100644 tools/diglim/compact_gen.c
 create mode 100644 tools/diglim/rpm_gen.c
 create mode 100644 tools/diglim/rpm_parser.c
 create mode 100644 tools/diglim/upload_digest_lists.c