1. 19 Sep, 2024 1 commit
    • Shu Han's avatar
      mm: call the security_mmap_file() LSM hook in remap_file_pages() · ea7e2d5e
      Shu Han authored
      The remap_file_pages syscall handler calls do_mmap() directly, which
      doesn't contain the LSM security check. And if the process has called
      personality(READ_IMPLIES_EXEC) before and remap_file_pages() is called for
      RW pages, this will actually result in remapping the pages to RWX,
      bypassing a W^X policy enforced by SELinux.
      
      So we should check prot by security_mmap_file LSM hook in the
      remap_file_pages syscall handler before do_mmap() is called. Otherwise, it
      potentially permits an attacker to bypass a W^X policy enforced by
      SELinux.
      
      The bypass is similar to CVE-2016-10044, which bypass the same thing via
      AIO and can be found in [1].
      
      The PoC:
      
      $ cat > test.c
      
      int main(void) {
      	size_t pagesz = sysconf(_SC_PAGE_SIZE);
      	int mfd = syscall(SYS_memfd_create, "test", 0);
      	const char *buf = mmap(NULL, 4 * pagesz, PROT_READ | PROT_WRITE,
      		MAP_SHARED, mfd, 0);
      	unsigned int old = syscall(SYS_personality, 0xffffffff);
      	syscall(SYS_personality, READ_IMPLIES_EXEC | old);
      	syscall(SYS_remap_file_pages, buf, pagesz, 0, 2, 0);
      	syscall(SYS_personality, old);
      	// show the RWX page exists even if W^X policy is enforced
      	int fd = open("/proc/self/maps", O_RDONLY);
      	unsigned char buf2[1024];
      	while (1) {
      		int ret = read(fd, buf2, 1024);
      		if (ret <= 0) break;
      		write(1, buf2, ret);
      	}
      	close(fd);
      }
      
      $ gcc test.c -o test
      $ ./test | grep rwx
      7f1836c34000-7f1836c35000 rwxs 00002000 00:01 2050 /memfd:test (deleted)
      
      Link: https://project-zero.issues.chromium.org/issues/42452389 [1]
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarShu Han <ebpqwerty472123@gmail.com>
      Acked-by: default avatarStephen Smalley <stephen.smalley.work@gmail.com>
      [PM: subject line tweaks]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      ea7e2d5e
  2. 09 Sep, 2024 2 commits
    • Mickaël Salaün's avatar
      security: Update file_set_fowner documentation · 19c9d55d
      Mickaël Salaün authored
      Highlight that the file_set_fowner hook is now called with a lock held.
      
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: Casey Schaufler <casey@schaufler-ca.com>
      Cc: Christian Brauner <brauner@kernel.org>
      Cc: James Morris <jmorris@namei.org>
      Cc: Jann Horn <jannh@google.com>
      Cc: Ondrej Mosnacek <omosnace@redhat.com>
      Cc: Paul Moore <paul@paul-moore.com>
      Cc: Serge E. Hallyn <serge@hallyn.com>
      Cc: Stephen Smalley <stephen.smalley.work@gmail.com>
      Signed-off-by: default avatarMickaël Salaün <mic@digikod.net>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      19c9d55d
    • Mickaël Salaün's avatar
      fs: Fix file_set_fowner LSM hook inconsistencies · 26f20438
      Mickaël Salaün authored
      The fcntl's F_SETOWN command sets the process that handle SIGIO/SIGURG
      for the related file descriptor.  Before this change, the
      file_set_fowner LSM hook was always called, ignoring the VFS logic which
      may not actually change the process that handles SIGIO (e.g. TUN, TTY,
      dnotify), nor update the related UID/EUID.
      
      Moreover, because security_file_set_fowner() was called without lock
      (e.g. f_owner.lock), concurrent F_SETOWN commands could result to a race
      condition and inconsistent LSM states (e.g. SELinux's fown_sid) compared
      to struct fown_struct's UID/EUID.
      
      This change makes sure the LSM states are always in sync with the VFS
      state by moving the security_file_set_fowner() call close to the
      UID/EUID updates and using the same f_owner.lock .
      
      Rename f_modown() to __f_setown() to simplify code.
      
      Cc: stable@vger.kernel.org
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: Casey Schaufler <casey@schaufler-ca.com>
      Cc: Christian Brauner <brauner@kernel.org>
      Cc: James Morris <jmorris@namei.org>
      Cc: Jann Horn <jannh@google.com>
      Cc: Ondrej Mosnacek <omosnace@redhat.com>
      Cc: Paul Moore <paul@paul-moore.com>
      Cc: Serge E. Hallyn <serge@hallyn.com>
      Cc: Stephen Smalley <stephen.smalley.work@gmail.com>
      Fixes: 1da177e4 ("Linux-2.6.12-rc2")
      Signed-off-by: default avatarMickaël Salaün <mic@digikod.net>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      26f20438
  3. 29 Aug, 2024 1 commit
  4. 26 Aug, 2024 1 commit
  5. 22 Aug, 2024 3 commits
    • Yang Li's avatar
      ipe: Remove duplicated include in ipe.c · f5dafb89
      Yang Li authored
      The header files eval.h is included twice in ipe.c,
      so one inclusion of each can be removed.
      Reported-by: default avatarAbaci Robot <abaci@linux.alibaba.com>
      Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=9796Signed-off-by: default avatarYang Li <yang.lee@linux.alibaba.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      f5dafb89
    • KP Singh's avatar
      lsm: replace indirect LSM hook calls with static calls · 417c5643
      KP Singh authored
      LSM hooks are currently invoked from a linked list as indirect calls
      which are invoked using retpolines as a mitigation for speculative
      attacks (Branch History / Target injection) and add extra overhead which
      is especially bad in kernel hot paths:
      
      security_file_ioctl:
         0xff...0320 <+0>:	endbr64
         0xff...0324 <+4>:	push   %rbp
         0xff...0325 <+5>:	push   %r15
         0xff...0327 <+7>:	push   %r14
         0xff...0329 <+9>:	push   %rbx
         0xff...032a <+10>:	mov    %rdx,%rbx
         0xff...032d <+13>:	mov    %esi,%ebp
         0xff...032f <+15>:	mov    %rdi,%r14
         0xff...0332 <+18>:	mov    $0xff...7030,%r15
         0xff...0339 <+25>:	mov    (%r15),%r15
         0xff...033c <+28>:	test   %r15,%r15
         0xff...033f <+31>:	je     0xff...0358 <security_file_ioctl+56>
         0xff...0341 <+33>:	mov    0x18(%r15),%r11
         0xff...0345 <+37>:	mov    %r14,%rdi
         0xff...0348 <+40>:	mov    %ebp,%esi
         0xff...034a <+42>:	mov    %rbx,%rdx
      
         0xff...034d <+45>:	call   0xff...2e0 <__x86_indirect_thunk_array+352>
         			       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      
          Indirect calls that use retpolines leading to overhead, not just due
          to extra instruction but also branch misses.
      
         0xff...0352 <+50>:	test   %eax,%eax
         0xff...0354 <+52>:	je     0xff...0339 <security_file_ioctl+25>
         0xff...0356 <+54>:	jmp    0xff...035a <security_file_ioctl+58>
         0xff...0358 <+56>:	xor    %eax,%eax
         0xff...035a <+58>:	pop    %rbx
         0xff...035b <+59>:	pop    %r14
         0xff...035d <+61>:	pop    %r15
         0xff...035f <+63>:	pop    %rbp
         0xff...0360 <+64>:	jmp    0xff...47c4 <__x86_return_thunk>
      
      The indirect calls are not really needed as one knows the addresses of
      enabled LSM callbacks at boot time and only the order can possibly
      change at boot time with the lsm= kernel command line parameter.
      
      An array of static calls is defined per LSM hook and the static calls
      are updated at boot time once the order has been determined.
      
      With the hook now exposed as a static call, one can see that the
      retpolines are no longer there and the LSM callbacks are invoked
      directly:
      
      security_file_ioctl:
         0xff...0ca0 <+0>:	endbr64
         0xff...0ca4 <+4>:	nopl   0x0(%rax,%rax,1)
         0xff...0ca9 <+9>:	push   %rbp
         0xff...0caa <+10>:	push   %r14
         0xff...0cac <+12>:	push   %rbx
         0xff...0cad <+13>:	mov    %rdx,%rbx
         0xff...0cb0 <+16>:	mov    %esi,%ebp
         0xff...0cb2 <+18>:	mov    %rdi,%r14
         0xff...0cb5 <+21>:	jmp    0xff...0cc7 <security_file_ioctl+39>
        			       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         Static key enabled for SELinux
      
         0xffffffff818f0cb7 <+23>:	jmp    0xff...0cde <security_file_ioctl+62>
         				^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      
         Static key enabled for BPF LSM. This is something that is changed to
         default to false to avoid the existing side effect issues of BPF LSM
         [1] in a subsequent patch.
      
         0xff...0cb9 <+25>:	xor    %eax,%eax
         0xff...0cbb <+27>:	xchg   %ax,%ax
         0xff...0cbd <+29>:	pop    %rbx
         0xff...0cbe <+30>:	pop    %r14
         0xff...0cc0 <+32>:	pop    %rbp
         0xff...0cc1 <+33>:	cs jmp 0xff...0000 <__x86_return_thunk>
         0xff...0cc7 <+39>:	endbr64
         0xff...0ccb <+43>:	mov    %r14,%rdi
         0xff...0cce <+46>:	mov    %ebp,%esi
         0xff...0cd0 <+48>:	mov    %rbx,%rdx
         0xff...0cd3 <+51>:	call   0xff...3230 <selinux_file_ioctl>
         			       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         Direct call to SELinux.
      
         0xff...0cd8 <+56>:	test   %eax,%eax
         0xff...0cda <+58>:	jne    0xff...0cbd <security_file_ioctl+29>
         0xff...0cdc <+60>:	jmp    0xff...0cb7 <security_file_ioctl+23>
         0xff...0cde <+62>:	endbr64
         0xff...0ce2 <+66>:	mov    %r14,%rdi
         0xff...0ce5 <+69>:	mov    %ebp,%esi
         0xff...0ce7 <+71>:	mov    %rbx,%rdx
         0xff...0cea <+74>:	call   0xff...e220 <bpf_lsm_file_ioctl>
         			       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         Direct call to BPF LSM.
      
         0xff...0cef <+79>:	test   %eax,%eax
         0xff...0cf1 <+81>:	jne    0xff...0cbd <security_file_ioctl+29>
         0xff...0cf3 <+83>:	jmp    0xff...0cb9 <security_file_ioctl+25>
         0xff...0cf5 <+85>:	endbr64
         0xff...0cf9 <+89>:	mov    %r14,%rdi
         0xff...0cfc <+92>:	mov    %ebp,%esi
         0xff...0cfe <+94>:	mov    %rbx,%rdx
         0xff...0d01 <+97>:	pop    %rbx
         0xff...0d02 <+98>:	pop    %r14
         0xff...0d04 <+100>:	pop    %rbp
         0xff...0d05 <+101>:	ret
         0xff...0d06 <+102>:	int3
         0xff...0d07 <+103>:	int3
         0xff...0d08 <+104>:	int3
         0xff...0d09 <+105>:	int3
      
      While this patch uses static_branch_unlikely indicating that an LSM hook
      is likely to be not present. In most cases this is still a better choice
      as even when an LSM with one hook is added, empty slots are created for
      all LSM hooks (especially when many LSMs that do not initialize most
      hooks are present on the system).
      
      There are some hooks that don't use the call_int_hook or
      call_void_hook. These hooks are updated to use a new macro called
      lsm_for_each_hook where the lsm_callback is directly invoked as an
      indirect call.
      
      Below are results of the relevant Unixbench system benchmarks with BPF LSM
      and SELinux enabled with default policies enabled with and without these
      patches.
      
      Benchmark                                          Delta(%): (+ is better)
      ==========================================================================
      Execl Throughput                                             +1.9356
      File Write 1024 bufsize 2000 maxblocks                       +6.5953
      Pipe Throughput                                              +9.5499
      Pipe-based Context Switching                                 +3.0209
      Process Creation                                             +2.3246
      Shell Scripts (1 concurrent)                                 +1.4975
      System Call Overhead                                         +2.7815
      System Benchmarks Index Score (Partial Only):                +3.4859
      
      In the best case, some syscalls like eventfd_create benefitted to about
      ~10%.
      Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
      Reviewed-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
      Reviewed-by: default avatarKees Cook <keescook@chromium.org>
      Acked-by: default avatarSong Liu <song@kernel.org>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: default avatarKP Singh <kpsingh@kernel.org>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      417c5643
    • KP Singh's avatar
      lsm: count the LSMs enabled at compile time · d51e783c
      KP Singh authored
      These macros are a clever trick to determine a count of the number of
      LSMs that are enabled in the config to ascertain the maximum number of
      static calls that need to be configured per LSM hook.
      
      Without this one would need to generate static calls for the total
      number of LSMs in the kernel (even if they are not compiled) times the
      number of LSM hooks which ends up being quite wasteful.
      Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
      Suggested-by: default avatarKui-Feng Lee <sinquersw@gmail.com>
      Suggested-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Reviewed-by: default avatarKees Cook <keescook@chromium.org>
      Reviewed-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
      Reviewed-by: default avatarJohn Johansen <john.johansen@canonical.com>
      Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
      Acked-by: default avatarSong Liu <song@kernel.org>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Nacked-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
      Signed-off-by: default avatarKP Singh <kpsingh@kernel.org>
      [PM: added IPE to the count during merge]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      d51e783c
  6. 20 Aug, 2024 22 commits
    • KP Singh's avatar
      kernel: Add helper macros for loop unrolling · 7cff549d
      KP Singh authored
      This helps in easily initializing blocks of code (e.g. static calls and
      keys).
      
      UNROLL(N, MACRO, __VA_ARGS__) calls MACRO N times with the first
      argument as the index of the iteration. This allows string pasting to
      create unique tokens for variable names, function calls etc.
      
      As an example:
      
      	#include <linux/unroll.h>
      
      	#define MACRO(N, a, b)            \
      		int add_##N(int a, int b) \
      		{                         \
      			return a + b + N; \
      		}
      
      	UNROLL(2, MACRO, x, y)
      
      expands to:
      
      	int add_0(int x, int y)
      	{
      		return x + y + 0;
      	}
      
      	int add_1(int x, int y)
      	{
      		return x + y + 1;
      	}
      Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
      Reviewed-by: default avatarKees Cook <keescook@chromium.org>
      Reviewed-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
      Reviewed-by: default avatarJohn Johansen <john.johansen@canonical.com>
      Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
      Acked-by: default avatarSong Liu <song@kernel.org>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
      Nacked-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
      Signed-off-by: default avatarKP Singh <kpsingh@kernel.org>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      7cff549d
    • KP Singh's avatar
      init/main.c: Initialize early LSMs after arch code, static keys and calls. · 77b644c3
      KP Singh authored
      With LSMs using static calls and static keys, early_lsm_init needs to
      wait for setup_arch for architecture specific functionality which
      includes jump tables and static calls to be initialized.
      
      Since not all architectures call jump_table_init in setup_arch,
      explicitly call both jump_table_init and static_call_init before
      early_security_init.
      
      This only affects "early LSMs" i.e. only lockdown when
      CONFIG_SECURITY_LOCKDOWN_LSM_EARLY is set.
      Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
      Signed-off-by: default avatarKP Singh <kpsingh@kernel.org>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      77b644c3
    • Fan Wu's avatar
      MAINTAINERS: add IPE entry with Fan Wu as maintainer · e4b0b54f
      Fan Wu authored
      Add a MAINTAINERS entry for the Integrity Policy Enforcement (IPE) LSM.
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      [PM: removed changelog, updated description per email thread]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      e4b0b54f
    • Deven Bowers's avatar
      documentation: add IPE documentation · ac673187
      Deven Bowers authored
      Add IPE's admin and developer documentation to the kernel tree.
      Co-developed-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      ac673187
    • Deven Bowers's avatar
      ipe: kunit test for parser · 10ca05a7
      Deven Bowers authored
      Add various happy/unhappy unit tests for both IPE's policy parser.
      
      Besides, a test suite for IPE functionality is available at
      https://github.com/microsoft/ipe/tree/test-suiteSigned-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      10ca05a7
    • Deven Bowers's avatar
      scripts: add boot policy generation program · ba199dc9
      Deven Bowers authored
      Enables an IPE policy to be enforced from kernel start, enabling access
      control based on trust from kernel startup. This is accomplished by
      transforming an IPE policy indicated by CONFIG_IPE_BOOT_POLICY into a
      c-string literal that is parsed at kernel startup as an unsigned policy.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      ba199dc9
    • Fan Wu's avatar
      ipe: enable support for fs-verity as a trust provider · 31f8c868
      Fan Wu authored
      Enable IPE policy authors to indicate trust for a singular fsverity
      file, identified by the digest information, through "fsverity_digest"
      and all files using valid fsverity builtin signatures via
      "fsverity_signature".
      
      This enables file-level integrity claims to be expressed in IPE,
      allowing individual files to be authorized, giving some flexibility
      for policy authors. Such file-level claims are important to be expressed
      for enforcing the integrity of packages, as well as address some of the
      scalability issues in a sole dm-verity based solution (# of loop back
      devices, etc).
      
      This solution cannot be done in userspace as the minimum threat that
      IPE should mitigate is an attacker downloads malicious payload with
      all required dependencies. These dependencies can lack the userspace
      check, bypassing the protection entirely. A similar attack succeeds if
      the userspace component is replaced with a version that does not
      perform the check. As a result, this can only be done in the common
      entry point - the kernel.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      31f8c868
    • Fan Wu's avatar
      fsverity: expose verified fsverity built-in signatures to LSMs · 7c373e4f
      Fan Wu authored
      This patch enhances fsverity's capabilities to support both integrity and
      authenticity protection by introducing the exposure of built-in
      signatures through a new LSM hook. This functionality allows LSMs,
      e.g. IPE, to enforce policies based on the authenticity and integrity of
      files, specifically focusing on built-in fsverity signatures. It enables
      a policy enforcement layer within LSMs for fsverity, offering granular
      control over the usage of authenticity claims. For instance, a policy
      could be established to only permit the execution of all files with
      verified built-in fsverity signatures.
      
      The introduction of a security_inode_setintegrity() hook call within
      fsverity's workflow ensures that the verified built-in signature of a file
      is exposed to LSMs. This enables LSMs to recognize and label fsverity files
      that contain a verified built-in fsverity signature. This hook is invoked
      subsequent to the fsverity_verify_signature() process, guaranteeing the
      signature's verification against fsverity's keyring. This mechanism is
      crucial for maintaining system security, as it operates in kernel space,
      effectively thwarting attempts by malicious binaries to bypass user space
      stack interactions.
      
      The second to last commit in this patch set will add a link to the IPE
      documentation in fsverity.rst.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Acked-by: default avatarEric Biggers <ebiggers@google.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      7c373e4f
    • Fan Wu's avatar
      lsm: add security_inode_setintegrity() hook · fb55e177
      Fan Wu authored
      This patch introduces a new hook to save inode's integrity
      data. For example, for fsverity enabled files, LSMs can use this hook to
      save the existence of verified fsverity builtin signature into the inode's
      security blob, and LSMs can make access decisions based on this data.
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      [PM: subject line tweak, removed changelog]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      fb55e177
    • Deven Bowers's avatar
      ipe: add support for dm-verity as a trust provider · e155858d
      Deven Bowers authored
      Allows author of IPE policy to indicate trust for a singular dm-verity
      volume, identified by roothash, through "dmverity_roothash" and all
      signed and validated dm-verity volumes, through "dmverity_signature".
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      [PM: fixed some line length issues in the comments]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      e155858d
    • Deven Bowers's avatar
      dm-verity: expose root hash digest and signature data to LSMs · a6af7bc3
      Deven Bowers authored
      dm-verity provides a strong guarantee of a block device's integrity. As
      a generic way to check the integrity of a block device, it provides
      those integrity guarantees to its higher layers, including the filesystem
      level.
      
      However, critical security metadata like the dm-verity roothash and its
      signing information are not easily accessible to the LSMs.
      To address this limitation, this patch introduces a mechanism to store
      and manage these essential security details within a newly added LSM blob
      in the block_device structure.
      
      This addition allows LSMs to make access control decisions on the integrity
      data stored within the block_device, enabling more flexible security
      policies. For instance, LSMs can now revoke access to dm-verity devices
      based on their roothashes, ensuring that only authorized and verified
      content is accessible. Additionally, LSMs can enforce policies to only
      allow files from dm-verity devices that have a valid digital signature to
      execute, effectively blocking any unsigned files from execution, thus
      enhancing security against unauthorized modifications.
      
      The patch includes new hook calls, `security_bdev_setintegrity()`, in
      dm-verity to expose the dm-verity roothash and the roothash signature to
      LSMs via preresume() callback. By using the preresume() callback, it
      ensures that the security metadata is consistently in sync with the
      metadata of the dm-verity target in the current active mapping table.
      The hook calls are depended on CONFIG_SECURITY.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Reviewed-by: default avatarMikulas Patocka <mpatocka@redhat.com>
      [PM: moved sig_size field as discussed]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      a6af7bc3
    • Deven Bowers's avatar
      block,lsm: add LSM blob and new LSM hooks for block devices · b55d26bd
      Deven Bowers authored
      This patch introduces a new LSM blob to the block_device structure,
      enabling the security subsystem to store security-sensitive data related
      to block devices. Currently, for a device mapper's mapped device containing
      a dm-verity target, critical security information such as the roothash and
      its signing state are not readily accessible. Specifically, while the
      dm-verity volume creation process passes the dm-verity roothash and its
      signature from userspace to the kernel, the roothash is stored privately
      within the dm-verity target, and its signature is discarded
      post-verification. This makes it extremely hard for the security subsystem
      to utilize these data.
      
      With the addition of the LSM blob to the block_device structure, the
      security subsystem can now retain and manage important security metadata
      such as the roothash and the signing state of a dm-verity by storing them
      inside the blob. Access decisions can then be based on these stored data.
      
      The implementation follows the same approach used for security blobs in
      other structures like struct file, struct inode, and struct superblock.
      The initialization of the security blob occurs after the creation of the
      struct block_device, performed by the security subsystem. Similarly, the
      security blob is freed by the security subsystem before the struct
      block_device is deallocated or freed.
      
      This patch also introduces a new hook security_bdev_setintegrity() to save
      block device's integrity data to the new LSM blob. For example, for
      dm-verity, it can use this hook to expose its roothash and signing state
      to LSMs, then LSMs can save these data into the LSM blob.
      
      Please note that the new hook should be invoked every time the security
      information is updated to keep these data current. For example, in
      dm-verity, if the mapping table is reloaded and configured to use a
      different dm-verity target with a new roothash and signing information,
      the previously stored data in the LSM blob will become obsolete. It is
      crucial to re-invoke the hook to refresh these data and ensure they are up
      to date. This necessity arises from the design of device-mapper, where a
      device-mapper device is first created, and then targets are subsequently
      loaded into it. These targets can be modified multiple times during the
      device's lifetime. Therefore, while the LSM blob is allocated during the
      creation of the block device, its actual contents are not initialized at
      this stage and can change substantially over time. This includes
      alterations from data that the LSM 'trusts' to those it does not, making
      it essential to handle these changes correctly. Failure to address this
      dynamic aspect could potentially allow for bypassing LSM checks.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      [PM: merge fuzz, subject line tweaks]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      b55d26bd
    • Deven Bowers's avatar
      ipe: add permissive toggle · a68916ea
      Deven Bowers authored
      IPE, like SELinux, supports a permissive mode. This mode allows policy
      authors to test and evaluate IPE policy without it affecting their
      programs. When the mode is changed, a 1404 AUDIT_MAC_STATUS will
      be reported.
      
      This patch adds the following audit records:
      
          audit: MAC_STATUS enforcing=0 old_enforcing=1 auid=4294967295
            ses=4294967295 enabled=1 old-enabled=1 lsm=ipe res=1
          audit: MAC_STATUS enforcing=1 old_enforcing=0 auid=4294967295
            ses=4294967295 enabled=1 old-enabled=1 lsm=ipe res=1
      
      The audit record only emit when the value from the user input is
      different from the current enforce value.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      a68916ea
    • Deven Bowers's avatar
      audit,ipe: add IPE auditing support · f44554b5
      Deven Bowers authored
      Users of IPE require a way to identify when and why an operation fails,
      allowing them to both respond to violations of policy and be notified
      of potentially malicious actions on their systems with respect to IPE
      itself.
      
      This patch introduces 3 new audit events.
      
      AUDIT_IPE_ACCESS(1420) indicates the result of an IPE policy evaluation
      of a resource.
      AUDIT_IPE_CONFIG_CHANGE(1421) indicates the current active IPE policy
      has been changed to another loaded policy.
      AUDIT_IPE_POLICY_LOAD(1422) indicates a new IPE policy has been loaded
      into the kernel.
      
      This patch also adds support for success auditing, allowing users to
      identify why an allow decision was made for a resource. However, it is
      recommended to use this option with caution, as it is quite noisy.
      
      Here are some examples of the new audit record types:
      
      AUDIT_IPE_ACCESS(1420):
      
          audit: AUDIT1420 ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=1
            pid=297 comm="sh" path="/root/vol/bin/hello" dev="tmpfs"
            ino=3897 rule="op=EXECUTE boot_verified=TRUE action=ALLOW"
      
          audit: AUDIT1420 ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=1
            pid=299 comm="sh" path="/mnt/ipe/bin/hello" dev="dm-0"
            ino=2 rule="DEFAULT action=DENY"
      
          audit: AUDIT1420 ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=1
           pid=300 path="/tmp/tmpdp2h1lub/deny/bin/hello" dev="tmpfs"
            ino=131 rule="DEFAULT action=DENY"
      
      The above three records were generated when the active IPE policy only
      allows binaries from the initramfs to run. The three identical `hello`
      binary were placed at different locations, only the first hello from
      the rootfs(initramfs) was allowed.
      
      Field ipe_op followed by the IPE operation name associated with the log.
      
      Field ipe_hook followed by the name of the LSM hook that triggered the IPE
      event.
      
      Field enforcing followed by the enforcement state of IPE. (it will be
      introduced in the next commit)
      
      Field pid followed by the pid of the process that triggered the IPE
      event.
      
      Field comm followed by the command line program name of the process that
      triggered the IPE event.
      
      Field path followed by the file's path name.
      
      Field dev followed by the device name as found in /dev where the file is
      from.
      Note that for device mappers it will use the name `dm-X` instead of
      the name in /dev/mapper.
      For a file in a temp file system, which is not from a device, it will use
      `tmpfs` for the field.
      The implementation of this part is following another existing use case
      LSM_AUDIT_DATA_INODE in security/lsm_audit.c
      
      Field ino followed by the file's inode number.
      
      Field rule followed by the IPE rule made the access decision. The whole
      rule must be audited because the decision is based on the combination of
      all property conditions in the rule.
      
      Along with the syscall audit event, user can know why a blocked
      happened. For example:
      
          audit: AUDIT1420 ipe_op=EXECUTE ipe_hook=BPRM_CHECK enforcing=1
            pid=2138 comm="bash" path="/mnt/ipe/bin/hello" dev="dm-0"
            ino=2 rule="DEFAULT action=DENY"
          audit[1956]: SYSCALL arch=c000003e syscall=59
            success=no exit=-13 a0=556790138df0 a1=556790135390 a2=5567901338b0
            a3=ab2a41a67f4f1f4e items=1 ppid=147 pid=1956 auid=4294967295 uid=0
            gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0
            ses=4294967295 comm="bash" exe="/usr/bin/bash" key=(null)
      
      The above two records showed bash used execve to run "hello" and got
      blocked by IPE. Note that the IPE records are always prior to a SYSCALL
      record.
      
      AUDIT_IPE_CONFIG_CHANGE(1421):
      
          audit: AUDIT1421
            old_active_pol_name="Allow_All" old_active_pol_version=0.0.0
            old_policy_digest=sha256:E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649
            new_active_pol_name="boot_verified" new_active_pol_version=0.0.0
            new_policy_digest=sha256:820EEA5B40CA42B51F68962354BA083122A20BB846F
            auid=4294967295 ses=4294967295 lsm=ipe res=1
      
      The above record showed the current IPE active policy switch from
      `Allow_All` to `boot_verified` along with the version and the hash
      digest of the two policies. Note IPE can only have one policy active
      at a time, all access decision evaluation is based on the current active
      policy.
      The normal procedure to deploy a policy is loading the policy to deploy
      into the kernel first, then switch the active policy to it.
      
      AUDIT_IPE_POLICY_LOAD(1422):
      
          audit: AUDIT1422 policy_name="boot_verified" policy_version=0.0.0
            policy_digest=sha256:820EEA5B40CA42B51F68962354BA083122A20BB846F2676
            auid=4294967295 ses=4294967295 lsm=ipe res=1
      
      The above record showed a new policy has been loaded into the kernel
      with the policy name, policy version and policy hash.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      [PM: subject line tweak]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      f44554b5
    • Deven Bowers's avatar
      ipe: add userspace interface · 2261306f
      Deven Bowers authored
      As is typical with LSMs, IPE uses securityfs as its interface with
      userspace. for a complete list of the interfaces and the respective
      inputs/outputs, please see the documentation under
      admin-guide/LSM/ipe.rst
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      2261306f
    • Fan Wu's avatar
      lsm: add new securityfs delete function · 7138679f
      Fan Wu authored
      When deleting a directory in the security file system, the existing
      securityfs_remove requires the directory to be empty, otherwise
      it will do nothing. This leads to a potential risk that the security
      file system might be in an unclean state when the intended deletion
      did not happen.
      
      This commit introduces a new function securityfs_recursive_remove
      to recursively delete a directory without leaving an unclean state.
      Co-developed-by: default avatarChristian Brauner (Microsoft) <brauner@kernel.org>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      [PM: subject line tweak]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      7138679f
    • Fan Wu's avatar
      ipe: introduce 'boot_verified' as a trust provider · a8a74df1
      Fan Wu authored
      IPE is designed to provide system level trust guarantees, this usually
      implies that trust starts from bootup with a hardware root of trust,
      which validates the bootloader. After this, the bootloader verifies
      the kernel and the initramfs.
      
      As there's no currently supported integrity method for initramfs, and
      it's typically already verified by the bootloader. This patch introduces
      a new IPE property `boot_verified` which allows author of IPE policy to
      indicate trust for files from initramfs.
      
      The implementation of this feature utilizes the newly added
      `initramfs_populated` hook. This hook marks the superblock of the rootfs
      after the initramfs has been unpacked into it.
      
      Before mounting the real rootfs on top of the initramfs, initramfs
      script will recursively remove all files and directories on the
      initramfs. This is typically implemented by using switch_root(8)
      (https://man7.org/linux/man-pages/man8/switch_root.8.html).
      Therefore the initramfs will be empty and not accessible after the real
      rootfs takes over. It is advised to switch to a different policy
      that doesn't rely on the `boot_verified` property after this point.
      This ensures that the trust policies remain relevant and effective
      throughout the system's operation.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      a8a74df1
    • Fan Wu's avatar
      initramfs,lsm: add a security hook to do_populate_rootfs() · 2fea0c26
      Fan Wu authored
      This patch introduces a new hook to notify security system that the
      content of initramfs has been unpacked into the rootfs.
      
      Upon receiving this notification, the security system can activate
      a policy to allow only files that originated from the initramfs to
      execute or load into kernel during the early stages of booting.
      
      This approach is crucial for minimizing the attack surface by
      ensuring that only trusted files from the initramfs are operational
      in the critical boot phase.
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      [PM: subject line tweak]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      2fea0c26
    • Deven Bowers's avatar
      ipe: add LSM hooks on execution and kernel read · 52443cb6
      Deven Bowers authored
      IPE's initial goal is to control both execution and the loading of
      kernel modules based on the system's definition of trust. It
      accomplishes this by plugging into the security hooks for
      bprm_check_security, file_mprotect, mmap_file, kernel_load_data,
      and kernel_read_data.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      52443cb6
    • Deven Bowers's avatar
      ipe: add evaluation loop · 05a35163
      Deven Bowers authored
      Introduce a core evaluation function in IPE that will be triggered by
      various security hooks (e.g., mmap, bprm_check, kexec). This function
      systematically assesses actions against the defined IPE policy, by
      iterating over rules specific to the action being taken. This critical
      addition enables IPE to enforce its security policies effectively,
      ensuring that actions intercepted by these hooks are scrutinized for policy
      compliance before they are allowed to proceed.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      Reviewed-by: default avatarSerge Hallyn <serge@hallyn.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      05a35163
    • Deven Bowers's avatar
      ipe: add policy parser · 54a88cd2
      Deven Bowers authored
      IPE's interpretation of the what the user trusts is accomplished through
      its policy. IPE's design is to not provide support for a single trust
      provider, but to support multiple providers to enable the end-user to
      choose the best one to seek their needs.
      
      This requires the policy to be rather flexible and modular so that
      integrity providers, like fs-verity, dm-verity, or some other system,
      can plug into the policy with minimal code changes.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      [PM: added NULL check in parse_rule() as discussed]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      54a88cd2
    • Deven Bowers's avatar
      lsm: add IPE lsm · 03115077
      Deven Bowers authored
      Integrity Policy Enforcement (IPE) is an LSM that provides an
      complimentary approach to Mandatory Access Control than existing LSMs
      today.
      
      Existing LSMs have centered around the concept of access to a resource
      should be controlled by the current user's credentials. IPE's approach,
      is that access to a resource should be controlled by the system's trust
      of a current resource.
      
      The basis of this approach is defining a global policy to specify which
      resource can be trusted.
      Signed-off-by: default avatarDeven Bowers <deven.desai@linux.microsoft.com>
      Signed-off-by: default avatarFan Wu <wufan@linux.microsoft.com>
      [PM: subject line tweak]
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      03115077
  7. 15 Aug, 2024 1 commit
  8. 12 Aug, 2024 2 commits
    • Paul Moore's avatar
      lsm: add the inode_free_security_rcu() LSM implementation hook · 63dff3e4
      Paul Moore authored
      The LSM framework has an existing inode_free_security() hook which
      is used by LSMs that manage state associated with an inode, but
      due to the use of RCU to protect the inode, special care must be
      taken to ensure that the LSMs do not fully release the inode state
      until it is safe from a RCU perspective.
      
      This patch implements a new inode_free_security_rcu() implementation
      hook which is called when it is safe to free the LSM's internal inode
      state.  Unfortunately, this new hook does not have access to the inode
      itself as it may already be released, so the existing
      inode_free_security() hook is retained for those LSMs which require
      access to the inode.
      
      Cc: stable@vger.kernel.org
      Reported-by: syzbot+5446fbf332b0602ede0b@syzkaller.appspotmail.com
      Closes: https://lore.kernel.org/r/00000000000076ba3b0617f65cc8@google.comSigned-off-by: default avatarPaul Moore <paul@paul-moore.com>
      63dff3e4
    • Paul Moore's avatar
      lsm: cleanup lsm_hooks.h · 711f5c5c
      Paul Moore authored
      Some cleanup and style corrections for lsm_hooks.h.
      
       * Drop the lsm_inode_alloc() extern declaration, it is not needed.
       * Relocate lsm_get_xattr_slot() and extern variables in the file to
         improve grouping of related objects.
       * Don't use tabs to needlessly align structure fields.
      Reviewed-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
      Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
      711f5c5c
  9. 31 Jul, 2024 2 commits
  10. 29 Jul, 2024 5 commits