History

Merge tag 'lsm-pr-20240105' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm

Pull security module updates from Paul Moore: - Add three new syscalls: lsm_list_modules(), lsm_get_self_attr(), and lsm_set_self_attr(). The first syscall simply lists the LSMs enabled, while the second and third get and set the current process' LSM attributes. Yes, these syscalls may provide similar functionality to what can be found under /proc or /sys, but they were designed to support multiple, simultaneaous (stacked) LSMs from the start as opposed to the current /proc based solutions which were created at a time when only one LSM was allowed to be active at a given time. We have spent considerable time discussing ways to extend the existing /proc interfaces to support multiple, simultaneaous LSMs and even our best ideas have been far too ugly to support as a kernel API; after +20 years in the kernel, I felt the LSM layer had established itself enough to justify a handful of syscalls. Support amongst the individual LSM developers has been nearly unanimous, with a single objection coming from Tetsuo (TOMOYO) as he is worried that the LSM_ID_XXX token concept will make it more difficult for out-of-tree LSMs to survive. Several members of the LSM community have demonstrated the ability for out-of-tree LSMs to continue to exist by picking high/unused LSM_ID values as well as pointing out that many kernel APIs rely on integer identifiers, e.g. syscalls (!), but unfortunately Tetsuo's objections remain. My personal opinion is that while I have no interest in penalizing out-of-tree LSMs, I'm not going to penalize in-tree development to support out-of-tree development, and I view this as a necessary step forward to support the push for expanded LSM stacking and reduce our reliance on /proc and /sys which has occassionally been problematic for some container users. Finally, we have included the linux-api folks on (all?) recent revisions of the patchset and addressed all of their concerns. - Add a new security_file_ioctl_compat() LSM hook to handle the 32-bit ioctls on 64-bit systems problem. This patch includes support for all of the existing LSMs which provide ioctl hooks, although it turns out only SELinux actually cares about the individual ioctls. It is worth noting that while Casey (Smack) and Tetsuo (TOMOYO) did not give explicit ACKs to this patch, they did both indicate they are okay with the changes. - Fix a potential memory leak in the CALIPSO code when IPv6 is disabled at boot. While it's good that we are fixing this, I doubt this is something users are seeing in the wild as you need to both disable IPv6 and then attempt to configure IPv6 labeled networking via NetLabel/CALIPSO; that just doesn't make much sense. Normally this would go through netdev, but Jakub asked me to take this patch and of all the trees I maintain, the LSM tree seemed like the best fit. - Update the LSM MAINTAINERS entry with additional information about our process docs, patchwork, bug reporting, etc. I also noticed that the Lockdown LSM is missing a dedicated MAINTAINERS entry so I've added that to the pull request. I've been working with one of the major Lockdown authors/contributors to see if they are willing to step up and assume a Lockdown maintainer role; hopefully that will happen soon, but in the meantime I'll continue to look after it. - Add a handful of mailmap entries for Serge Hallyn and myself. * tag 'lsm-pr-20240105' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm: (27 commits) lsm: new security_file_ioctl_compat() hook lsm: Add a __counted_by() annotation to lsm_ctx.ctx calipso: fix memory leak in netlbl_calipso_add_pass() selftests: remove the LSM_ID_IMA check in lsm/lsm_list_modules_test MAINTAINERS: add an entry for the lockdown LSM MAINTAINERS: update the LSM entry mailmap: add entries for Serge Hallyn's dead accounts mailmap: update/replace my old email addresses lsm: mark the lsm_id variables are marked as static lsm: convert security_setselfattr() to use memdup_user() lsm: align based on pointer length in lsm_fill_user_ctx() lsm: consolidate buffer size handling into lsm_fill_user_ctx() lsm: correct error codes in security_getselfattr() lsm: cleanup the size counters in security_getselfattr() lsm: don't yet account for IMA in LSM_CONFIG_COUNT calculation lsm: drop LSM_ID_IMA LSM: selftests for Linux Security Module syscalls SELinux: Add selfattr hooks AppArmor: Add selfattr hooks Smack: implement setselfattr and getselfattr hooks ...

Linus Torvalds committed 2 years ago

Commit 063a7ce2 parents 9f9310b f1bb47a66 files · +1784 −122Browse files

Unified · Split

66 files
  1. .mailmap +4 −0
  2. Documentation/userspace-api/index.rst +1 −0
  3. Documentation/userspace-api/lsm.rst +73 −0
  4. MAINTAINERS +14 −3
  5. arch/alpha/kernel/syscalls/syscall.tbl +3 −0
  6. arch/arm/tools/syscall.tbl +3 −0
  7. arch/arm64/include/asm/unistd.h +1 −1
  8. arch/arm64/include/asm/unistd32.h +6 −0
  9. arch/m68k/kernel/syscalls/syscall.tbl +3 −0
  10. arch/microblaze/kernel/syscalls/syscall.tbl +3 −0
  11. arch/mips/kernel/syscalls/syscall_n32.tbl +3 −0
  12. arch/mips/kernel/syscalls/syscall_n64.tbl +3 −0
  13. arch/mips/kernel/syscalls/syscall_o32.tbl +3 −0
  14. arch/parisc/kernel/syscalls/syscall.tbl +3 −0
  15. arch/powerpc/kernel/syscalls/syscall.tbl +3 −0
  16. arch/s390/kernel/syscalls/syscall.tbl +3 −0
  17. arch/sh/kernel/syscalls/syscall.tbl +3 −0
  18. arch/sparc/kernel/syscalls/syscall.tbl +3 −0
  19. arch/x86/entry/syscalls/syscall_32.tbl +3 −0
  20. arch/x86/entry/syscalls/syscall_64.tbl +3 −0
  21. arch/xtensa/kernel/syscalls/syscall.tbl +3 −0
  22. fs/ioctl.c +1 −2
  23. fs/proc/base.c +15 −14
  24. fs/proc/internal.h +1 −1
  25. include/linux/lsm_hook_defs.h +6 −0
  26. include/linux/lsm_hooks.h +15 −2
  27. include/linux/security.h +50 −6
  28. include/linux/syscalls.h +6 −0
  29. include/uapi/asm-generic/unistd.h +8 −1
  30. include/uapi/linux/lsm.h +90 −0
  31. kernel/sys_ni.c +3 −0
  32. net/netlabel/netlabel_calipso.c +26 −23
  33. security/Makefile +1 −0
  34. security/apparmor/include/procattr.h +1 −1
  35. security/apparmor/lsm.c +83 −7
  36. security/apparmor/procattr.c +6 −4
  37. security/bpf/hooks.c +8 −1
  38. security/commoncap.c +7 −1
  39. security/landlock/cred.c +1 −1
  40. security/landlock/fs.c +1 −1
  41. security/landlock/net.c +1 −1
  42. security/landlock/ptrace.c +1 −1
  43. security/landlock/setup.c +6 −0
  44. security/landlock/setup.h +1 −0
  45. security/loadpin/loadpin.c +8 −1
  46. security/lockdown/lockdown.c +7 −1
  47. security/lsm_syscalls.c +120 −0
  48. security/safesetid/lsm.c +8 −1
  49. security/security.c +261 −12
  50. security/selinux/hooks.c +145 −28
  51. security/smack/smack_lsm.c +87 −6
  52. security/tomoyo/tomoyo.c +9 −1
  53. security/yama/yama_lsm.c +7 −1
  54. tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl +5 −0
  55. tools/perf/arch/powerpc/entry/syscalls/syscall.tbl +5 −0
  56. tools/perf/arch/s390/entry/syscalls/syscall.tbl +5 −0
  57. tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +5 −0
  58. tools/testing/selftests/Makefile +1 −0
  59. tools/testing/selftests/lsm/.gitignore +1 −0
  60. tools/testing/selftests/lsm/Makefile +17 −0
  61. tools/testing/selftests/lsm/common.c +89 −0
  62. tools/testing/selftests/lsm/common.h +33 −0
  63. tools/testing/selftests/lsm/config +3 −0
  64. tools/testing/selftests/lsm/lsm_get_self_attr_test.c +275 −0
  65. tools/testing/selftests/lsm/lsm_list_modules_test.c +137 −0
  66. tools/testing/selftests/lsm/lsm_set_self_attr_test.c +74 −0
.mailmap+4−0
@@ -478,6 +478,8 @@ Paul E. McKenney <paulmck@kernel.org> <paulmck@linux.vnet.ibm.com> · 477 unmodified lines
478Paul E. McKenney <paulmck@kernel.org> <paulmck@us.ibm.com>478Paul E. McKenney <paulmck@kernel.org> <paulmck@us.ibm.com>
479Paul Mackerras <paulus@ozlabs.org> <paulus@samba.org>479Paul Mackerras <paulus@ozlabs.org> <paulus@samba.org>
480Paul Mackerras <paulus@ozlabs.org> <paulus@au1.ibm.com>480Paul Mackerras <paulus@ozlabs.org> <paulus@au1.ibm.com>
481Paul Moore <paul@paul-moore.com> <paul.moore@hp.com>
482Paul Moore <paul@paul-moore.com> <pmoore@redhat.com>
481Pavankumar Kondeti <quic_pkondeti@quicinc.com> <pkondeti@codeaurora.org>483Pavankumar Kondeti <quic_pkondeti@quicinc.com> <pkondeti@codeaurora.org>
482Peter A Jonsson <pj@ludd.ltu.se>484Peter A Jonsson <pj@ludd.ltu.se>
483Peter Oruba <peter.oruba@amd.com>485Peter Oruba <peter.oruba@amd.com>
@@ -542,6 +544,8 @@ Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk> · 58 unmodified lines
542Sebastian Reichel <sre@kernel.org> <sre@debian.org>544Sebastian Reichel <sre@kernel.org> <sre@debian.org>
543Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de>545Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de>
544Senthilkumar N L <quic_snlakshm@quicinc.com> <snlakshm@codeaurora.org>546Senthilkumar N L <quic_snlakshm@quicinc.com> <snlakshm@codeaurora.org>
547Serge Hallyn <sergeh@kernel.org> <serge.hallyn@canonical.com>
548Serge Hallyn <sergeh@kernel.org> <serue@us.ibm.com>
545Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com>549Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com>
546Shannon Nelson <shannon.nelson@amd.com> <snelson@pensando.io>550Shannon Nelson <shannon.nelson@amd.com> <snelson@pensando.io>
547Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@intel.com>551Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@intel.com>
Documentation/userspace-api/index.rst+1−0
@@ -33,6 +33,7 @@ place where this information is gathered. · 32 unmodified lines
33 sysfs-platform_profile33 sysfs-platform_profile
34 vduse34 vduse
35 futex235 futex2
36 lsm
36 37
37.. only:: subproject and html38.. only:: subproject and html
38 39
Documentation/userspace-api/lsm.rst+73−0
@@ -0,0 +1,73 @@
1.. SPDX-License-Identifier: GPL-2.0
2.. Copyright (C) 2022 Casey Schaufler <casey@schaufler-ca.com>
3.. Copyright (C) 2022 Intel Corporation
4
5=====================================
6Linux Security Modules
7=====================================
8
9:Author: Casey Schaufler
10:Date: July 2023
11
12Linux security modules (LSM) provide a mechanism to implement
13additional access controls to the Linux security policies.
14
15The various security modules may support any of these attributes:
16
17``LSM_ATTR_CURRENT`` is the current, active security context of the
18process.
19The proc filesystem provides this value in ``/proc/self/attr/current``.
20This is supported by the SELinux, Smack and AppArmor security modules.
21Smack also provides this value in ``/proc/self/attr/smack/current``.
22AppArmor also provides this value in ``/proc/self/attr/apparmor/current``.
23
24``LSM_ATTR_EXEC`` is the security context of the process at the time the
25current image was executed.
26The proc filesystem provides this value in ``/proc/self/attr/exec``.
27This is supported by the SELinux and AppArmor security modules.
28AppArmor also provides this value in ``/proc/self/attr/apparmor/exec``.
29
30``LSM_ATTR_FSCREATE`` is the security context of the process used when
31creating file system objects.
32The proc filesystem provides this value in ``/proc/self/attr/fscreate``.
33This is supported by the SELinux security module.
34
35``LSM_ATTR_KEYCREATE`` is the security context of the process used when
36creating key objects.
37The proc filesystem provides this value in ``/proc/self/attr/keycreate``.
38This is supported by the SELinux security module.
39
40``LSM_ATTR_PREV`` is the security context of the process at the time the
41current security context was set.
42The proc filesystem provides this value in ``/proc/self/attr/prev``.
43This is supported by the SELinux and AppArmor security modules.
44AppArmor also provides this value in ``/proc/self/attr/apparmor/prev``.
45
46``LSM_ATTR_SOCKCREATE`` is the security context of the process used when
47creating socket objects.
48The proc filesystem provides this value in ``/proc/self/attr/sockcreate``.
49This is supported by the SELinux security module.
50
51Kernel interface
52================
53
54Set a security attribute of the current process
55-----------------------------------------------
56
57.. kernel-doc:: security/lsm_syscalls.c
58 :identifiers: sys_lsm_set_self_attr
59
60Get the specified security attributes of the current process
61------------------------------------------------------------
62
63.. kernel-doc:: security/lsm_syscalls.c
64 :identifiers: sys_lsm_get_self_attr
65
66.. kernel-doc:: security/lsm_syscalls.c
67 :identifiers: sys_lsm_list_modules
68
69Additional documentation
70========================
71
72* Documentation/security/lsm.rst
73* Documentation/security/lsm-development.rst
MAINTAINERS+14−3
@@ -12417,6 +12417,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/har · 12416 unmodified lines
12417F: Documentation/admin-guide/LSM/LoadPin.rst12417F: Documentation/admin-guide/LSM/LoadPin.rst
12418F: security/loadpin/12418F: security/loadpin/
12419 12419
12420LOCKDOWN SECURITY MODULE
12421L: linux-security-module@vger.kernel.org
12422S: Odd Fixes
12423T: git https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git
12424F: security/lockdown/
12425
12420LOCKING PRIMITIVES12426LOCKING PRIMITIVES
12421M: Peter Zijlstra <peterz@infradead.org>12427M: Peter Zijlstra <peterz@infradead.org>
12422M: Ingo Molnar <mingo@redhat.com>12428M: Ingo Molnar <mingo@redhat.com>
@@ -19455,12 +19461,17 @@ SECURITY SUBSYSTEM · 7032 unmodified lines
19455M: Paul Moore <paul@paul-moore.com>19461M: Paul Moore <paul@paul-moore.com>
19456M: James Morris <jmorris@namei.org>19462M: James Morris <jmorris@namei.org>
19457M: "Serge E. Hallyn" <serge@hallyn.com>19463M: "Serge E. Hallyn" <serge@hallyn.com>
19458L: linux-security-module@vger.kernel.org (suggested Cc:)19464L: linux-security-module@vger.kernel.org
19459S: Supported19465S: Supported
19460W: http://kernsec.org/19466Q: https://patchwork.kernel.org/project/linux-security-module/list
19461T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git19467B: mailto:linux-security-module@vger.kernel.org
19468P: https://github.com/LinuxSecurityModule/kernel/blob/main/README.md
19469T: git https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git
19470F: include/uapi/linux/lsm.h
19462F: security/19471F: security/
19472F: tools/testing/selftests/lsm/
19463X: security/selinux/19473X: security/selinux/
19474K: \bsecurity_[a-z_0-9]\+\b
19464 19475
19465SELINUX SECURITY MODULE19476SELINUX SECURITY MODULE
19466M: Paul Moore <paul@paul-moore.com>19477M: Paul Moore <paul@paul-moore.com>
arch/alpha/kernel/syscalls/syscall.tbl+3−0
@@ -498,3 +498,6 @@ · 497 unmodified lines
498566 common futex_requeue sys_futex_requeue498566 common futex_requeue sys_futex_requeue
499567 common statmount sys_statmount499567 common statmount sys_statmount
500568 common listmount sys_listmount500568 common listmount sys_listmount
501569 common lsm_get_self_attr sys_lsm_get_self_attr
502570 common lsm_set_self_attr sys_lsm_set_self_attr
503571 common lsm_list_modules sys_lsm_list_modules
arch/arm/tools/syscall.tbl+3−0
@@ -472,3 +472,6 @@ · 471 unmodified lines
472456 common futex_requeue sys_futex_requeue472456 common futex_requeue sys_futex_requeue
473457 common statmount sys_statmount473457 common statmount sys_statmount
474458 common listmount sys_listmount474458 common listmount sys_listmount
475459 common lsm_get_self_attr sys_lsm_get_self_attr
476460 common lsm_set_self_attr sys_lsm_set_self_attr
477461 common lsm_list_modules sys_lsm_list_modules
arch/arm64/include/asm/unistd.h+1−1
@@ -39,7 +39,7 @@ · 38 unmodified lines
39#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5)39#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5)
40#define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800)40#define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800)
41 41
42#define __NR_compat_syscalls 45942#define __NR_compat_syscalls 462
43#endif43#endif
44 44
45#define __ARCH_WANT_SYS_CLONE45#define __ARCH_WANT_SYS_CLONE
arch/arm64/include/asm/unistd32.h+6−0
@@ -923,6 +923,12 @@ __SYSCALL(__NR_futex_requeue, sys_futex_requeue) · 922 unmodified lines
923__SYSCALL(__NR_statmount, sys_statmount)923__SYSCALL(__NR_statmount, sys_statmount)
924#define __NR_listmount 458924#define __NR_listmount 458
925__SYSCALL(__NR_listmount, sys_listmount)925__SYSCALL(__NR_listmount, sys_listmount)
926#define __NR_lsm_get_self_attr 459
927__SYSCALL(__NR_lsm_get_self_attr, sys_lsm_get_self_attr)
928#define __NR_lsm_set_self_attr 460
929__SYSCALL(__NR_lsm_set_self_attr, sys_lsm_set_self_attr)
930#define __NR_lsm_list_modules 461
931__SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules)
926 932
927/*933/*
928 * Please add new compat syscalls above this comment and update934 * Please add new compat syscalls above this comment and update
arch/m68k/kernel/syscalls/syscall.tbl+3−0
@@ -458,3 +458,6 @@ · 457 unmodified lines
458456 common futex_requeue sys_futex_requeue458456 common futex_requeue sys_futex_requeue
459457 common statmount sys_statmount459457 common statmount sys_statmount
460458 common listmount sys_listmount460458 common listmount sys_listmount
461459 common lsm_get_self_attr sys_lsm_get_self_attr
462460 common lsm_set_self_attr sys_lsm_set_self_attr
463461 common lsm_list_modules sys_lsm_list_modules
arch/microblaze/kernel/syscalls/syscall.tbl+3−0
@@ -464,3 +464,6 @@ · 463 unmodified lines
464456 common futex_requeue sys_futex_requeue464456 common futex_requeue sys_futex_requeue
465457 common statmount sys_statmount465457 common statmount sys_statmount
466458 common listmount sys_listmount466458 common listmount sys_listmount
467459 common lsm_get_self_attr sys_lsm_get_self_attr
468460 common lsm_set_self_attr sys_lsm_set_self_attr
469461 common lsm_list_modules sys_lsm_list_modules
arch/mips/kernel/syscalls/syscall_n32.tbl+3−0
@@ -397,3 +397,6 @@ · 396 unmodified lines
397456 n32 futex_requeue sys_futex_requeue397456 n32 futex_requeue sys_futex_requeue
398457 n32 statmount sys_statmount398457 n32 statmount sys_statmount
399458 n32 listmount sys_listmount399458 n32 listmount sys_listmount
400459 n32 lsm_get_self_attr sys_lsm_get_self_attr
401460 n32 lsm_set_self_attr sys_lsm_set_self_attr
402461 n32 lsm_list_modules sys_lsm_list_modules
arch/mips/kernel/syscalls/syscall_n64.tbl+3−0
@@ -373,3 +373,6 @@ · 372 unmodified lines
373456 n64 futex_requeue sys_futex_requeue373456 n64 futex_requeue sys_futex_requeue
374457 n64 statmount sys_statmount374457 n64 statmount sys_statmount
375458 n64 listmount sys_listmount375458 n64 listmount sys_listmount
376459 n64 lsm_get_self_attr sys_lsm_get_self_attr
377460 n64 lsm_set_self_attr sys_lsm_set_self_attr
378461 n64 lsm_list_modules sys_lsm_list_modules
arch/mips/kernel/syscalls/syscall_o32.tbl+3−0
@@ -446,3 +446,6 @@ · 445 unmodified lines
446456 o32 futex_requeue sys_futex_requeue446456 o32 futex_requeue sys_futex_requeue
447457 o32 statmount sys_statmount447457 o32 statmount sys_statmount
448458 o32 listmount sys_listmount448458 o32 listmount sys_listmount
449459 o32 lsm_get_self_attr sys_lsm_get_self_attr
450460 o32 lsm_set_self_attr sys_lsm_set_self_attr
451461 o32 lsm_list_modules sys_lsm_list_modules
arch/parisc/kernel/syscalls/syscall.tbl+3−0
@@ -457,3 +457,6 @@ · 456 unmodified lines
457456 common futex_requeue sys_futex_requeue457456 common futex_requeue sys_futex_requeue
458457 common statmount sys_statmount458457 common statmount sys_statmount
459458 common listmount sys_listmount459458 common listmount sys_listmount
460459 common lsm_get_self_attr sys_lsm_get_self_attr
461460 common lsm_set_self_attr sys_lsm_set_self_attr
462461 common lsm_list_modules sys_lsm_list_modules
arch/powerpc/kernel/syscalls/syscall.tbl+3−0
@@ -545,3 +545,6 @@ · 544 unmodified lines
545456 common futex_requeue sys_futex_requeue545456 common futex_requeue sys_futex_requeue
546457 common statmount sys_statmount546457 common statmount sys_statmount
547458 common listmount sys_listmount547458 common listmount sys_listmount
548459 common lsm_get_self_attr sys_lsm_get_self_attr
549460 common lsm_set_self_attr sys_lsm_set_self_attr
550461 common lsm_list_modules sys_lsm_list_modules
arch/s390/kernel/syscalls/syscall.tbl+3−0
@@ -461,3 +461,6 @@ · 460 unmodified lines
461456 common futex_requeue sys_futex_requeue sys_futex_requeue461456 common futex_requeue sys_futex_requeue sys_futex_requeue
462457 common statmount sys_statmount sys_statmount462457 common statmount sys_statmount sys_statmount
463458 common listmount sys_listmount sys_listmount463458 common listmount sys_listmount sys_listmount
464459 common lsm_get_self_attr sys_lsm_get_self_attr sys_lsm_get_self_attr
465460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr
466461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules
arch/sh/kernel/syscalls/syscall.tbl+3−0
@@ -461,3 +461,6 @@ · 460 unmodified lines
461456 common futex_requeue sys_futex_requeue461456 common futex_requeue sys_futex_requeue
462457 common statmount sys_statmount462457 common statmount sys_statmount
463458 common listmount sys_listmount463458 common listmount sys_listmount
464459 common lsm_get_self_attr sys_lsm_get_self_attr
465460 common lsm_set_self_attr sys_lsm_set_self_attr
466461 common lsm_list_modules sys_lsm_list_modules
arch/sparc/kernel/syscalls/syscall.tbl+3−0
@@ -504,3 +504,6 @@ · 503 unmodified lines
504456 common futex_requeue sys_futex_requeue504456 common futex_requeue sys_futex_requeue
505457 common statmount sys_statmount505457 common statmount sys_statmount
506458 common listmount sys_listmount506458 common listmount sys_listmount
507459 common lsm_get_self_attr sys_lsm_get_self_attr
508460 common lsm_set_self_attr sys_lsm_set_self_attr
509461 common lsm_list_modules sys_lsm_list_modules
arch/x86/entry/syscalls/syscall_32.tbl+3−0
@@ -463,3 +463,6 @@ · 462 unmodified lines
463456 i386 futex_requeue sys_futex_requeue463456 i386 futex_requeue sys_futex_requeue
464457 i386 statmount sys_statmount464457 i386 statmount sys_statmount
465458 i386 listmount sys_listmount465458 i386 listmount sys_listmount
466459 i386 lsm_get_self_attr sys_lsm_get_self_attr
467460 i386 lsm_set_self_attr sys_lsm_set_self_attr
468461 i386 lsm_list_modules sys_lsm_list_modules
arch/x86/entry/syscalls/syscall_64.tbl+3−0
@@ -380,6 +380,9 @@ · 379 unmodified lines
380456 common futex_requeue sys_futex_requeue380456 common futex_requeue sys_futex_requeue
381457 common statmount sys_statmount381457 common statmount sys_statmount
382458 common listmount sys_listmount382458 common listmount sys_listmount
383459 common lsm_get_self_attr sys_lsm_get_self_attr
384460 common lsm_set_self_attr sys_lsm_set_self_attr
385461 common lsm_list_modules sys_lsm_list_modules
383 386
384#387#
385# Due to a historical design error, certain syscalls are numbered differently388# Due to a historical design error, certain syscalls are numbered differently
arch/xtensa/kernel/syscalls/syscall.tbl+3−0
@@ -429,3 +429,6 @@ · 428 unmodified lines
429456 common futex_requeue sys_futex_requeue429456 common futex_requeue sys_futex_requeue
430457 common statmount sys_statmount430457 common statmount sys_statmount
431458 common listmount sys_listmount431458 common listmount sys_listmount
432459 common lsm_get_self_attr sys_lsm_get_self_attr
433460 common lsm_set_self_attr sys_lsm_set_self_attr
434461 common lsm_list_modules sys_lsm_list_modules
fs/ioctl.c+1−2
@@ -920,8 +920,7 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, · 919 unmodified lines
920 if (!f.file)920 if (!f.file)
921 return -EBADF;921 return -EBADF;
922 922
923 /* RED-PEN how should LSM module know it's handling 32bit? */923 error = security_file_ioctl_compat(f.file, cmd, arg);
924 error = security_file_ioctl(f.file, cmd, arg);
925 if (error)924 if (error)
926 goto out;925 goto out;
927 926
fs/proc/base.c+15−14
@@ -97,6 +97,7 @@ · 96 unmodified lines
97#include <linux/resctrl.h>97#include <linux/resctrl.h>
98#include <linux/cn_proc.h>98#include <linux/cn_proc.h>
99#include <linux/ksm.h>99#include <linux/ksm.h>
100#include <uapi/linux/lsm.h>
100#include <trace/events/oom.h>101#include <trace/events/oom.h>
101#include "internal.h"102#include "internal.h"
102#include "fd.h"103#include "fd.h"
@@ -146,10 +147,10 @@ struct pid_entry { · 43 unmodified lines
146 NOD(NAME, (S_IFREG|(MODE)), \147 NOD(NAME, (S_IFREG|(MODE)), \
147 NULL, &proc_single_file_operations, \148 NULL, &proc_single_file_operations, \
148 { .proc_show = show } )149 { .proc_show = show } )
149#define ATTR(LSM, NAME, MODE) \150#define ATTR(LSMID, NAME, MODE) \
150 NOD(NAME, (S_IFREG|(MODE)), \151 NOD(NAME, (S_IFREG|(MODE)), \
151 NULL, &proc_pid_attr_operations, \152 NULL, &proc_pid_attr_operations, \
152 { .lsm = LSM })153 { .lsmid = LSMID })
153 154
154/*155/*
155 * Count the number of hardlinks for the pid_entry table, excluding the .156 * Count the number of hardlinks for the pid_entry table, excluding the .
@@ -2726,7 +2727,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, · 2570 unmodified lines
2726 if (!task)2727 if (!task)
2727 return -ESRCH;2728 return -ESRCH;
2728 2729
2729 length = security_getprocattr(task, PROC_I(inode)->op.lsm,2730 length = security_getprocattr(task, PROC_I(inode)->op.lsmid,
2730 file->f_path.dentry->d_name.name,2731 file->f_path.dentry->d_name.name,
2731 &p);2732 &p);
2732 put_task_struct(task);2733 put_task_struct(task);
@@ -2784,7 +2785,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, · 51 unmodified lines
2784 if (rv < 0)2785 if (rv < 0)
2785 goto out_free;2786 goto out_free;
2786 2787
2787 rv = security_setprocattr(PROC_I(inode)->op.lsm,2788 rv = security_setprocattr(PROC_I(inode)->op.lsmid,
2788 file->f_path.dentry->d_name.name, page,2789 file->f_path.dentry->d_name.name, page,
2789 count);2790 count);
2790 mutex_unlock(&current->signal->cred_guard_mutex);2791 mutex_unlock(&current->signal->cred_guard_mutex);
@@ -2833,27 +2834,27 @@ static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \ · 42 unmodified lines
2833 2834
2834#ifdef CONFIG_SECURITY_SMACK2835#ifdef CONFIG_SECURITY_SMACK
2835static const struct pid_entry smack_attr_dir_stuff[] = {2836static const struct pid_entry smack_attr_dir_stuff[] = {
2836 ATTR("smack", "current", 0666),2837 ATTR(LSM_ID_SMACK, "current", 0666),
2837};2838};
2838LSM_DIR_OPS(smack);2839LSM_DIR_OPS(smack);
2839#endif2840#endif
2840 2841
2841#ifdef CONFIG_SECURITY_APPARMOR2842#ifdef CONFIG_SECURITY_APPARMOR
2842static const struct pid_entry apparmor_attr_dir_stuff[] = {2843static const struct pid_entry apparmor_attr_dir_stuff[] = {
2843 ATTR("apparmor", "current", 0666),2844 ATTR(LSM_ID_APPARMOR, "current", 0666),
2844 ATTR("apparmor", "prev", 0444),2845 ATTR(LSM_ID_APPARMOR, "prev", 0444),
2845 ATTR("apparmor", "exec", 0666),2846 ATTR(LSM_ID_APPARMOR, "exec", 0666),
2846};2847};
2847LSM_DIR_OPS(apparmor);2848LSM_DIR_OPS(apparmor);
2848#endif2849#endif
2849 2850
2850static const struct pid_entry attr_dir_stuff[] = {2851static const struct pid_entry attr_dir_stuff[] = {
2851 ATTR(NULL, "current", 0666),2852 ATTR(LSM_ID_UNDEF, "current", 0666),
2852 ATTR(NULL, "prev", 0444),2853 ATTR(LSM_ID_UNDEF, "prev", 0444),
2853 ATTR(NULL, "exec", 0666),2854 ATTR(LSM_ID_UNDEF, "exec", 0666),
2854 ATTR(NULL, "fscreate", 0666),2855 ATTR(LSM_ID_UNDEF, "fscreate", 0666),
2855 ATTR(NULL, "keycreate", 0666),2856 ATTR(LSM_ID_UNDEF, "keycreate", 0666),
2856 ATTR(NULL, "sockcreate", 0666),2857 ATTR(LSM_ID_UNDEF, "sockcreate", 0666),
2857#ifdef CONFIG_SECURITY_SMACK2858#ifdef CONFIG_SECURITY_SMACK
2858 DIR("smack", 0555,2859 DIR("smack", 0555,
2859 proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops),2860 proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops),
fs/proc/internal.h+1−1
@@ -92,7 +92,7 @@ union proc_op { · 91 unmodified lines
92 int (*proc_show)(struct seq_file *m,92 int (*proc_show)(struct seq_file *m,
93 struct pid_namespace *ns, struct pid *pid,93 struct pid_namespace *ns, struct pid *pid,
94 struct task_struct *task);94 struct task_struct *task);
95 const char *lsm;95 int lsmid;
96};96};
97 97
98struct proc_inode {98struct proc_inode {
include/linux/lsm_hook_defs.h+6−0
@@ -171,6 +171,8 @@ LSM_HOOK(int, 0, file_alloc_security, struct file *file) · 170 unmodified lines
171LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file)171LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file)
172LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd,172LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd,
173 unsigned long arg)173 unsigned long arg)
174LSM_HOOK(int, 0, file_ioctl_compat, struct file *file, unsigned int cmd,
175 unsigned long arg)
174LSM_HOOK(int, 0, mmap_addr, unsigned long addr)176LSM_HOOK(int, 0, mmap_addr, unsigned long addr)
175LSM_HOOK(int, 0, mmap_file, struct file *file, unsigned long reqprot,177LSM_HOOK(int, 0, mmap_file, struct file *file, unsigned long reqprot,
176 unsigned long prot, unsigned long flags)178 unsigned long prot, unsigned long flags)
@@ -262,6 +264,10 @@ LSM_HOOK(int, 0, sem_semop, struct kern_ipc_perm *perm, struct sembuf *sops, · 85 unmodified lines
262LSM_HOOK(int, 0, netlink_send, struct sock *sk, struct sk_buff *skb)264LSM_HOOK(int, 0, netlink_send, struct sock *sk, struct sk_buff *skb)
263LSM_HOOK(void, LSM_RET_VOID, d_instantiate, struct dentry *dentry,265LSM_HOOK(void, LSM_RET_VOID, d_instantiate, struct dentry *dentry,
264 struct inode *inode)266 struct inode *inode)
267LSM_HOOK(int, -EOPNOTSUPP, getselfattr, unsigned int attr,
268 struct lsm_ctx __user *ctx, size_t *size, u32 flags)
269LSM_HOOK(int, -EOPNOTSUPP, setselfattr, unsigned int attr,
270 struct lsm_ctx *ctx, size_t size, u32 flags)
265LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name,271LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name,
266 char **value)272 char **value)
267LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size)273LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size)
include/linux/lsm_hooks.h+15−2
@@ -25,6 +25,7 @@ · 24 unmodified lines
25#ifndef __LINUX_LSM_HOOKS_H25#ifndef __LINUX_LSM_HOOKS_H
26#define __LINUX_LSM_HOOKS_H26#define __LINUX_LSM_HOOKS_H
27 27
28#include <uapi/linux/lsm.h>
28#include <linux/security.h>29#include <linux/security.h>
29#include <linux/init.h>30#include <linux/init.h>
30#include <linux/rculist.h>31#include <linux/rculist.h>
@@ -42,6 +43,18 @@ struct security_hook_heads { · 11 unmodified lines
42 #undef LSM_HOOK43 #undef LSM_HOOK
43} __randomize_layout;44} __randomize_layout;
44 45
46/**
47 * struct lsm_id - Identify a Linux Security Module.
48 * @lsm: name of the LSM, must be approved by the LSM maintainers
49 * @id: LSM ID number from uapi/linux/lsm.h
50 *
51 * Contains the information that identifies the LSM.
52 */
53struct lsm_id {
54 const char *name;
55 u64 id;
56};
57
45/*58/*
46 * Security module hook list structure.59 * Security module hook list structure.
47 * For use with generic list macros for common operations.60 * For use with generic list macros for common operations.
@@ -50,7 +63,7 @@ struct security_hook_list { · 2 unmodified lines
50 struct hlist_node list;63 struct hlist_node list;
51 struct hlist_head *head;64 struct hlist_head *head;
52 union security_list_options hook;65 union security_list_options hook;
53 const char *lsm;66 const struct lsm_id *lsmid;
54} __randomize_layout;67} __randomize_layout;
55 68
56/*69/*
@@ -104,7 +117,7 @@ extern struct security_hook_heads security_hook_heads; · 47 unmodified lines
104extern char *lsm_names;117extern char *lsm_names;
105 118
106extern void security_add_hooks(struct security_hook_list *hooks, int count,119extern void security_add_hooks(struct security_hook_list *hooks, int count,
107 const char *lsm);120 const struct lsm_id *lsmid);
108 121
109#define LSM_FLAG_LEGACY_MAJOR BIT(0)122#define LSM_FLAG_LEGACY_MAJOR BIT(0)
110#define LSM_FLAG_EXCLUSIVE BIT(1)123#define LSM_FLAG_EXCLUSIVE BIT(1)
include/linux/security.h+50−6
@@ -32,6 +32,7 @@ · 31 unmodified lines
32#include <linux/string.h>32#include <linux/string.h>
33#include <linux/mm.h>33#include <linux/mm.h>
34#include <linux/sockptr.h>34#include <linux/sockptr.h>
35#include <uapi/linux/lsm.h>
35 36
36struct linux_binprm;37struct linux_binprm;
37struct cred;38struct cred;
@@ -60,6 +61,7 @@ struct fs_parameter; · 22 unmodified lines
60enum fs_value_type;61enum fs_value_type;
61struct watch;62struct watch;
62struct watch_notification;63struct watch_notification;
64struct lsm_ctx;
63 65
64/* Default (no) options for the capable function */66/* Default (no) options for the capable function */
65#define CAP_OPT_NONE 0x067#define CAP_OPT_NONE 0x0
@@ -138,6 +140,8 @@ enum lockdown_reason { · 72 unmodified lines
138};140};
139 141
140extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1];142extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1];
143extern u32 lsm_active_cnt;
144extern const struct lsm_id *lsm_idlist[];
141 145
142/* These functions are in security/commoncap.c */146/* These functions are in security/commoncap.c */
143extern int cap_capable(const struct cred *cred, struct user_namespace *ns,147extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
@@ -261,6 +265,7 @@ int unregister_blocking_lsm_notifier(struct notifier_block *nb); · 117 unmodified lines
261/* prototypes */265/* prototypes */
262extern int security_init(void);266extern int security_init(void);
263extern int early_security_init(void);267extern int early_security_init(void);
268extern u64 lsm_name_to_attr(const char *name);
264 269
265/* Security operations */270/* Security operations */
266int security_binder_set_context_mgr(const struct cred *mgr);271int security_binder_set_context_mgr(const struct cred *mgr);
@@ -389,6 +394,8 @@ int security_file_permission(struct file *file, int mask); · 122 unmodified lines
389int security_file_alloc(struct file *file);394int security_file_alloc(struct file *file);
390void security_file_free(struct file *file);395void security_file_free(struct file *file);
391int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);396int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
397int security_file_ioctl_compat(struct file *file, unsigned int cmd,
398 unsigned long arg);
392int security_mmap_file(struct file *file, unsigned long prot,399int security_mmap_file(struct file *file, unsigned long prot,
393 unsigned long flags);400 unsigned long flags);
394int security_mmap_addr(unsigned long addr);401int security_mmap_addr(unsigned long addr);
@@ -470,10 +477,13 @@ int security_sem_semctl(struct kern_ipc_perm *sma, int cmd); · 75 unmodified lines
470int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,477int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,
471 unsigned nsops, int alter);478 unsigned nsops, int alter);
472void security_d_instantiate(struct dentry *dentry, struct inode *inode);479void security_d_instantiate(struct dentry *dentry, struct inode *inode);
473int security_getprocattr(struct task_struct *p, const char *lsm, const char *name,480int security_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
481 size_t __user *size, u32 flags);
482int security_setselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
483 size_t size, u32 flags);
484int security_getprocattr(struct task_struct *p, int lsmid, const char *name,
474 char **value);485 char **value);
475int security_setprocattr(const char *lsm, const char *name, void *value,486int security_setprocattr(int lsmid, const char *name, void *value, size_t size);
476 size_t size);
477int security_netlink_send(struct sock *sk, struct sk_buff *skb);487int security_netlink_send(struct sock *sk, struct sk_buff *skb);
478int security_ismaclabel(const char *name);488int security_ismaclabel(const char *name);
479int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);489int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
@@ -484,6 +494,8 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); · 4 unmodified lines
484int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);494int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
485int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);495int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
486int security_locked_down(enum lockdown_reason what);496int security_locked_down(enum lockdown_reason what);
497int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, size_t *uctx_len,
498 void *val, size_t val_len, u64 id, u64 flags);
487#else /* CONFIG_SECURITY */499#else /* CONFIG_SECURITY */
488 500
489static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)501static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -501,6 +513,11 @@ static inline int unregister_blocking_lsm_notifier(struct notifier_block *nb) · 11 unmodified lines
501 return 0;513 return 0;
502}514}
503 515
516static inline u64 lsm_name_to_attr(const char *name)
517{
518 return LSM_ATTR_UNDEF;
519}
520
504static inline void security_free_mnt_opts(void **mnt_opts)521static inline void security_free_mnt_opts(void **mnt_opts)
505{522{
506}523}
@@ -987,6 +1004,13 @@ static inline int security_file_ioctl(struct file *file, unsigned int cmd, · 480 unmodified lines
987 return 0;1004 return 0;
988}1005}
989 1006
1007static inline int security_file_ioctl_compat(struct file *file,
1008 unsigned int cmd,
1009 unsigned long arg)
1010{
1011 return 0;
1012}
1013
990static inline int security_mmap_file(struct file *file, unsigned long prot,1014static inline int security_mmap_file(struct file *file, unsigned long prot,
991 unsigned long flags)1015 unsigned long flags)
992{1016{
@@ -1337,14 +1361,28 @@ static inline void security_d_instantiate(struct dentry *dentry, · 344 unmodified lines
1337 struct inode *inode)1361 struct inode *inode)
1338{ }1362{ }
1339 1363
1340static inline int security_getprocattr(struct task_struct *p, const char *lsm,1364static inline int security_getselfattr(unsigned int attr,
1365 struct lsm_ctx __user *ctx,
1366 size_t __user *size, u32 flags)
1367{
1368 return -EOPNOTSUPP;
1369}
1370
1371static inline int security_setselfattr(unsigned int attr,
1372 struct lsm_ctx __user *ctx,
1373 size_t size, u32 flags)
1374{
1375 return -EOPNOTSUPP;
1376}
1377
1378static inline int security_getprocattr(struct task_struct *p, int lsmid,
1341 const char *name, char **value)1379 const char *name, char **value)
1342{1380{
1343 return -EINVAL;1381 return -EINVAL;
1344}1382}
1345 1383
1346static inline int security_setprocattr(const char *lsm, char *name,1384static inline int security_setprocattr(int lsmid, char *name, void *value,
1347 void *value, size_t size)1385 size_t size)
1348{1386{
1349 return -EINVAL;1387 return -EINVAL;
1350}1388}
@@ -1395,6 +1433,12 @@ static inline int security_locked_down(enum lockdown_reason what) · 44 unmodified lines
1395{1433{
1396 return 0;1434 return 0;
1397}1435}
1436static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx,
1437 size_t *uctx_len, void *val, size_t val_len,
1438 u64 id, u64 flags)
1439{
1440 return -EOPNOTSUPP;
1441}
1398#endif /* CONFIG_SECURITY */1442#endif /* CONFIG_SECURITY */
1399 1443
1400#if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)1444#if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
include/linux/syscalls.h+6−0
@@ -71,6 +71,7 @@ struct clone_args; · 70 unmodified lines
71struct open_how;71struct open_how;
72struct mount_attr;72struct mount_attr;
73struct landlock_ruleset_attr;73struct landlock_ruleset_attr;
74struct lsm_ctx;
74enum landlock_rule_type;75enum landlock_rule_type;
75struct cachestat_range;76struct cachestat_range;
76struct cachestat;77struct cachestat;
@@ -957,6 +958,11 @@ asmlinkage long sys_cachestat(unsigned int fd, · 880 unmodified lines
957 struct cachestat_range __user *cstat_range,958 struct cachestat_range __user *cstat_range,
958 struct cachestat __user *cstat, unsigned int flags);959 struct cachestat __user *cstat, unsigned int flags);
959asmlinkage long sys_map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags);960asmlinkage long sys_map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags);
961asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx,
962 size_t *size, __u32 flags);
963asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx,
964 size_t size, __u32 flags);
965asmlinkage long sys_lsm_list_modules(u64 *ids, size_t *size, u32 flags);
960 966
961/*967/*
962 * Architecture-specific system calls968 * Architecture-specific system calls
include/uapi/asm-generic/unistd.h+8−1
@@ -835,8 +835,15 @@ __SYSCALL(__NR_statmount, sys_statmount) · 834 unmodified lines
835#define __NR_listmount 458835#define __NR_listmount 458
836__SYSCALL(__NR_listmount, sys_listmount)836__SYSCALL(__NR_listmount, sys_listmount)
837 837
838#define __NR_lsm_get_self_attr 459
839__SYSCALL(__NR_lsm_get_self_attr, sys_lsm_get_self_attr)
840#define __NR_lsm_set_self_attr 460
841__SYSCALL(__NR_lsm_set_self_attr, sys_lsm_set_self_attr)
842#define __NR_lsm_list_modules 461
843__SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules)
844
838#undef __NR_syscalls845#undef __NR_syscalls
839#define __NR_syscalls 459846#define __NR_syscalls 462
840 847
841/*848/*
842 * 32 bit systems traditionally used different849 * 32 bit systems traditionally used different
include/uapi/linux/lsm.h+90−0
@@ -0,0 +1,90 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2/*
3 * Linux Security Modules (LSM) - User space API
4 *
5 * Copyright (C) 2022 Casey Schaufler <casey@schaufler-ca.com>
6 * Copyright (C) 2022 Intel Corporation
7 */
8
9#ifndef _UAPI_LINUX_LSM_H
10#define _UAPI_LINUX_LSM_H
11
12#include <linux/stddef.h>
13#include <linux/types.h>
14#include <linux/unistd.h>
15
16/**
17 * struct lsm_ctx - LSM context information
18 * @id: the LSM id number, see LSM_ID_XXX
19 * @flags: LSM specific flags
20 * @len: length of the lsm_ctx struct, @ctx and any other data or padding
21 * @ctx_len: the size of @ctx
22 * @ctx: the LSM context value
23 *
24 * The @len field MUST be equal to the size of the lsm_ctx struct
25 * plus any additional padding and/or data placed after @ctx.
26 *
27 * In all cases @ctx_len MUST be equal to the length of @ctx.
28 * If @ctx is a string value it should be nul terminated with
29 * @ctx_len equal to `strlen(@ctx) + 1`. Binary values are
30 * supported.
31 *
32 * The @flags and @ctx fields SHOULD only be interpreted by the
33 * LSM specified by @id; they MUST be set to zero/0 when not used.
34 */
35struct lsm_ctx {
36 __u64 id;
37 __u64 flags;
38 __u64 len;
39 __u64 ctx_len;
40 __u8 ctx[] __counted_by(ctx_len);
41};
42
43/*
44 * ID tokens to identify Linux Security Modules (LSMs)
45 *
46 * These token values are used to uniquely identify specific LSMs
47 * in the kernel as well as in the kernel's LSM userspace API.
48 *
49 * A value of zero/0 is considered undefined and should not be used
50 * outside the kernel. Values 1-99 are reserved for potential
51 * future use.
52 */
53#define LSM_ID_UNDEF 0
54#define LSM_ID_CAPABILITY 100
55#define LSM_ID_SELINUX 101
56#define LSM_ID_SMACK 102
57#define LSM_ID_TOMOYO 103
58#define LSM_ID_APPARMOR 104
59#define LSM_ID_YAMA 105
60#define LSM_ID_LOADPIN 106
61#define LSM_ID_SAFESETID 107
62#define LSM_ID_LOCKDOWN 108
63#define LSM_ID_BPF 109
64#define LSM_ID_LANDLOCK 110
65
66/*
67 * LSM_ATTR_XXX definitions identify different LSM attributes
68 * which are used in the kernel's LSM userspace API. Support
69 * for these attributes vary across the different LSMs. None
70 * are required.
71 *
72 * A value of zero/0 is considered undefined and should not be used
73 * outside the kernel. Values 1-99 are reserved for potential
74 * future use.
75 */
76#define LSM_ATTR_UNDEF 0
77#define LSM_ATTR_CURRENT 100
78#define LSM_ATTR_EXEC 101
79#define LSM_ATTR_FSCREATE 102
80#define LSM_ATTR_KEYCREATE 103
81#define LSM_ATTR_PREV 104
82#define LSM_ATTR_SOCKCREATE 105
83
84/*
85 * LSM_FLAG_XXX definitions identify special handling instructions
86 * for the API.
87 */
88#define LSM_FLAG_SINGLE 0x0001
89
90#endif /* _UAPI_LINUX_LSM_H */
kernel/sys_ni.c+3−0
@@ -171,6 +171,9 @@ COND_SYSCALL(landlock_add_rule); · 170 unmodified lines
171COND_SYSCALL(landlock_restrict_self);171COND_SYSCALL(landlock_restrict_self);
172COND_SYSCALL(fadvise64_64);172COND_SYSCALL(fadvise64_64);
173COND_SYSCALL_COMPAT(fadvise64_64);173COND_SYSCALL_COMPAT(fadvise64_64);
174COND_SYSCALL(lsm_get_self_attr);
175COND_SYSCALL(lsm_set_self_attr);
176COND_SYSCALL(lsm_list_modules);
174 177
175/* CONFIG_MMU only */178/* CONFIG_MMU only */
176COND_SYSCALL(swapon);179COND_SYSCALL(swapon);
net/netlabel/netlabel_calipso.c+26−23
@@ -54,6 +54,28 @@ static const struct nla_policy calipso_genl_policy[NLBL_CALIPSO_A_MAX + 1] = { · 53 unmodified lines
54 [NLBL_CALIPSO_A_MTYPE] = { .type = NLA_U32 },54 [NLBL_CALIPSO_A_MTYPE] = { .type = NLA_U32 },
55};55};
56 56
57static const struct netlbl_calipso_ops *calipso_ops;
58
59/**
60 * netlbl_calipso_ops_register - Register the CALIPSO operations
61 * @ops: ops to register
62 *
63 * Description:
64 * Register the CALIPSO packet engine operations.
65 *
66 */
67const struct netlbl_calipso_ops *
68netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops)
69{
70 return xchg(&calipso_ops, ops);
71}
72EXPORT_SYMBOL(netlbl_calipso_ops_register);
73
74static const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void)
75{
76 return READ_ONCE(calipso_ops);
77}
78
57/* NetLabel Command Handlers79/* NetLabel Command Handlers
58 */80 */
59/**81/**
@@ -96,15 +118,18 @@ static int netlbl_calipso_add_pass(struct genl_info *info, · 36 unmodified lines
96 *118 *
97 */119 */
98static int netlbl_calipso_add(struct sk_buff *skb, struct genl_info *info)120static int netlbl_calipso_add(struct sk_buff *skb, struct genl_info *info)
99
100{121{
101 int ret_val = -EINVAL;122 int ret_val = -EINVAL;
102 struct netlbl_audit audit_info;123 struct netlbl_audit audit_info;
124 const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
103 125
104 if (!info->attrs[NLBL_CALIPSO_A_DOI] ||126 if (!info->attrs[NLBL_CALIPSO_A_DOI] ||
105 !info->attrs[NLBL_CALIPSO_A_MTYPE])127 !info->attrs[NLBL_CALIPSO_A_MTYPE])
106 return -EINVAL;128 return -EINVAL;
107 129
130 if (!ops)
131 return -EOPNOTSUPP;
132
108 netlbl_netlink_auditinfo(&audit_info);133 netlbl_netlink_auditinfo(&audit_info);
109 switch (nla_get_u32(info->attrs[NLBL_CALIPSO_A_MTYPE])) {134 switch (nla_get_u32(info->attrs[NLBL_CALIPSO_A_MTYPE])) {
110 case CALIPSO_MAP_PASS:135 case CALIPSO_MAP_PASS:
@@ -363,28 +388,6 @@ int __init netlbl_calipso_genl_init(void) · 252 unmodified lines
363 return genl_register_family(&netlbl_calipso_gnl_family);388 return genl_register_family(&netlbl_calipso_gnl_family);
364}389}
365 390
366static const struct netlbl_calipso_ops *calipso_ops;
367
368/**
369 * netlbl_calipso_ops_register - Register the CALIPSO operations
370 * @ops: ops to register
371 *
372 * Description:
373 * Register the CALIPSO packet engine operations.
374 *
375 */
376const struct netlbl_calipso_ops *
377netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops)
378{
379 return xchg(&calipso_ops, ops);
380}
381EXPORT_SYMBOL(netlbl_calipso_ops_register);
382
383static const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void)
384{
385 return READ_ONCE(calipso_ops);
386}
387
388/**391/**
389 * calipso_doi_add - Add a new DOI to the CALIPSO protocol engine392 * calipso_doi_add - Add a new DOI to the CALIPSO protocol engine
390 * @doi_def: the DOI structure393 * @doi_def: the DOI structure
security/Makefile+1−0
@@ -7,6 +7,7 @@ obj-$(CONFIG_KEYS) += keys/ · 6 unmodified lines
7 7
8# always enable default capabilities8# always enable default capabilities
9obj-y += commoncap.o9obj-y += commoncap.o
10obj-$(CONFIG_SECURITY) += lsm_syscalls.o
10obj-$(CONFIG_MMU) += min_addr.o11obj-$(CONFIG_MMU) += min_addr.o
11 12
12# Object file lists13# Object file lists
security/apparmor/include/procattr.h+1−1
@@ -11,7 +11,7 @@ · 10 unmodified lines
11#ifndef __AA_PROCATTR_H11#ifndef __AA_PROCATTR_H
12#define __AA_PROCATTR_H12#define __AA_PROCATTR_H
13 13
14int aa_getprocattr(struct aa_label *label, char **string);14int aa_getprocattr(struct aa_label *label, char **string, bool newline);
15int aa_setprocattr_changehat(char *args, size_t size, int flags);15int aa_setprocattr_changehat(char *args, size_t size, int flags);
16 16
17#endif /* __AA_PROCATTR_H */17#endif /* __AA_PROCATTR_H */
security/apparmor/lsm.c+83−7
@@ -24,6 +24,7 @@ · 23 unmodified lines
24#include <linux/zstd.h>24#include <linux/zstd.h>
25#include <net/sock.h>25#include <net/sock.h>
26#include <uapi/linux/mount.h>26#include <uapi/linux/mount.h>
27#include <uapi/linux/lsm.h>
27 28
28#include "include/apparmor.h"29#include "include/apparmor.h"
29#include "include/apparmorfs.h"30#include "include/apparmorfs.h"
@@ -775,6 +776,46 @@ static int apparmor_sb_pivotroot(const struct path *old_path, · 745 unmodified lines
775 return error;776 return error;
776}777}
777 778
779static int apparmor_getselfattr(unsigned int attr, struct lsm_ctx __user *lx,
780 size_t *size, u32 flags)
781{
782 int error = -ENOENT;
783 struct aa_task_ctx *ctx = task_ctx(current);
784 struct aa_label *label = NULL;
785 char *value;
786
787 switch (attr) {
788 case LSM_ATTR_CURRENT:
789 label = aa_get_newest_label(cred_label(current_cred()));
790 break;
791 case LSM_ATTR_PREV:
792 if (ctx->previous)
793 label = aa_get_newest_label(ctx->previous);
794 break;
795 case LSM_ATTR_EXEC:
796 if (ctx->onexec)
797 label = aa_get_newest_label(ctx->onexec);
798 break;
799 default:
800 error = -EOPNOTSUPP;
801 break;
802 }
803
804 if (label) {
805 error = aa_getprocattr(label, &value, false);
806 if (error > 0)
807 error = lsm_fill_user_ctx(lx, size, value, error,
808 LSM_ID_APPARMOR, 0);
809 kfree(value);
810 }
811
812 aa_put_label(label);
813
814 if (error < 0)
815 return error;
816 return 1;
817}
818
778static int apparmor_getprocattr(struct task_struct *task, const char *name,819static int apparmor_getprocattr(struct task_struct *task, const char *name,
779 char **value)820 char **value)
780{821{
@@ -794,7 +835,7 @@ static int apparmor_getprocattr(struct task_struct *task, const char *name, · 13 unmodified lines
794 error = -EINVAL;835 error = -EINVAL;
795 836
796 if (label)837 if (label)
797 error = aa_getprocattr(label, value);838 error = aa_getprocattr(label, value, true);
798 839
799 aa_put_label(label);840 aa_put_label(label);
800 put_cred(cred);841 put_cred(cred);
@@ -802,8 +843,7 @@ static int apparmor_getprocattr(struct task_struct *task, const char *name, · 1 unmodified line
802 return error;843 return error;
803}844}
804 845
805static int apparmor_setprocattr(const char *name, void *value,846static int do_setattr(u64 attr, void *value, size_t size)
806 size_t size)
807{847{
808 char *command, *largs = NULL, *args = value;848 char *command, *largs = NULL, *args = value;
809 size_t arg_size;849 size_t arg_size;
@@ -834,7 +874,7 @@ static int apparmor_setprocattr(const char *name, void *value, · 24 unmodified lines
834 goto out;874 goto out;
835 875
836 arg_size = size - (args - (largs ? largs : (char *) value));876 arg_size = size - (args - (largs ? largs : (char *) value));
837 if (strcmp(name, "current") == 0) {877 if (attr == LSM_ATTR_CURRENT) {
838 if (strcmp(command, "changehat") == 0) {878 if (strcmp(command, "changehat") == 0) {
839 error = aa_setprocattr_changehat(args, arg_size,879 error = aa_setprocattr_changehat(args, arg_size,
840 AA_CHANGE_NOFLAGS);880 AA_CHANGE_NOFLAGS);
@@ -849,7 +889,7 @@ static int apparmor_setprocattr(const char *name, void *value, · 8 unmodified lines
849 error = aa_change_profile(args, AA_CHANGE_STACK);889 error = aa_change_profile(args, AA_CHANGE_STACK);
850 } else890 } else
851 goto fail;891 goto fail;
852 } else if (strcmp(name, "exec") == 0) {892 } else if (attr == LSM_ATTR_EXEC) {
853 if (strcmp(command, "exec") == 0)893 if (strcmp(command, "exec") == 0)
854 error = aa_change_profile(args, AA_CHANGE_ONEXEC);894 error = aa_change_profile(args, AA_CHANGE_ONEXEC);
855 else if (strcmp(command, "stack") == 0)895 else if (strcmp(command, "stack") == 0)
@@ -869,13 +909,42 @@ out: · 13 unmodified lines
869 909
870fail:910fail:
871 ad.subj_label = begin_current_label_crit_section();911 ad.subj_label = begin_current_label_crit_section();
872 ad.info = name;912 if (attr == LSM_ATTR_CURRENT)
913 ad.info = "current";
914 else if (attr == LSM_ATTR_EXEC)
915 ad.info = "exec";
916 else
917 ad.info = "invalid";
873 ad.error = error = -EINVAL;918 ad.error = error = -EINVAL;
874 aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL);919 aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL);
875 end_current_label_crit_section(ad.subj_label);920 end_current_label_crit_section(ad.subj_label);
876 goto out;921 goto out;
877}922}
878 923
924static int apparmor_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
925 size_t size, u32 flags)
926{
927 int rc;
928
929 if (attr != LSM_ATTR_CURRENT && attr != LSM_ATTR_EXEC)
930 return -EOPNOTSUPP;
931
932 rc = do_setattr(attr, ctx->ctx, ctx->ctx_len);
933 if (rc > 0)
934 return 0;
935 return rc;
936}
937
938static int apparmor_setprocattr(const char *name, void *value,
939 size_t size)
940{
941 int attr = lsm_name_to_attr(name);
942
943 if (attr)
944 return do_setattr(attr, value, size);
945 return -EINVAL;
946}
947
879/**948/**
880 * apparmor_bprm_committing_creds - do task cleanup on committing new creds949 * apparmor_bprm_committing_creds - do task cleanup on committing new creds
881 * @bprm: binprm for the exec (NOT NULL)950 * @bprm: binprm for the exec (NOT NULL)
@@ -1385,6 +1454,11 @@ struct lsm_blob_sizes apparmor_blob_sizes __ro_after_init = { · 503 unmodified lines
1385 .lbs_task = sizeof(struct aa_task_ctx),1454 .lbs_task = sizeof(struct aa_task_ctx),
1386};1455};
1387 1456
1457static const struct lsm_id apparmor_lsmid = {
1458 .name = "apparmor",
1459 .id = LSM_ID_APPARMOR,
1460};
1461
1388static struct security_hook_list apparmor_hooks[] __ro_after_init = {1462static struct security_hook_list apparmor_hooks[] __ro_after_init = {
1389 LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),1463 LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
1390 LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),1464 LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
@@ -1418,6 +1492,8 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = { · 27 unmodified lines
1418 LSM_HOOK_INIT(file_lock, apparmor_file_lock),1492 LSM_HOOK_INIT(file_lock, apparmor_file_lock),
1419 LSM_HOOK_INIT(file_truncate, apparmor_file_truncate),1493 LSM_HOOK_INIT(file_truncate, apparmor_file_truncate),
1420 1494
1495 LSM_HOOK_INIT(getselfattr, apparmor_getselfattr),
1496 LSM_HOOK_INIT(setselfattr, apparmor_setselfattr),
1421 LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),1497 LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
1422 LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),1498 LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
1423 1499
@@ -2202,7 +2278,7 @@ static int __init apparmor_init(void) · 778 unmodified lines
2202 goto buffers_out;2278 goto buffers_out;
2203 }2279 }
2204 security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks),2280 security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks),
2205 "apparmor");2281 &apparmor_lsmid);
2206 2282
2207 /* Report that AppArmor successfully initialized */2283 /* Report that AppArmor successfully initialized */
2208 apparmor_initialized = 1;2284 apparmor_initialized = 1;
security/apparmor/procattr.c+6−4
@@ -20,6 +20,7 @@ · 19 unmodified lines
20 * aa_getprocattr - Return the label information for @label20 * aa_getprocattr - Return the label information for @label
21 * @label: the label to print label info about (NOT NULL)21 * @label: the label to print label info about (NOT NULL)
22 * @string: Returns - string containing the label info (NOT NULL)22 * @string: Returns - string containing the label info (NOT NULL)
23 * @newline: indicates that a newline should be added
23 *24 *
24 * Requires: label != NULL && string != NULL25 * Requires: label != NULL && string != NULL
25 *26 *
@@ -27,7 +28,7 @@ · 1 unmodified line
27 *28 *
28 * Returns: size of string placed in @string else error code on failure29 * Returns: size of string placed in @string else error code on failure
29 */30 */
30int aa_getprocattr(struct aa_label *label, char **string)31int aa_getprocattr(struct aa_label *label, char **string, bool newline)
31{32{
32 struct aa_ns *ns = labels_ns(label);33 struct aa_ns *ns = labels_ns(label);
33 struct aa_ns *current_ns = aa_get_current_ns();34 struct aa_ns *current_ns = aa_get_current_ns();
@@ -57,11 +58,12 @@ int aa_getprocattr(struct aa_label *label, char **string) · 23 unmodified lines
57 return len;58 return len;
58 }59 }
59 60
60 (*string)[len] = '\n';61 if (newline)
61 (*string)[len + 1] = 0;62 (*string)[len++] = '\n';
63 (*string)[len] = 0;
62 64
63 aa_put_ns(current_ns);65 aa_put_ns(current_ns);
64 return len + 1;66 return len;
65}67}
66 68
67/**69/**
security/bpf/hooks.c+8−1
@@ -5,6 +5,7 @@ · 4 unmodified lines
5 */5 */
6#include <linux/lsm_hooks.h>6#include <linux/lsm_hooks.h>
7#include <linux/bpf_lsm.h>7#include <linux/bpf_lsm.h>
8#include <uapi/linux/lsm.h>
8 9
9static struct security_hook_list bpf_lsm_hooks[] __ro_after_init = {10static struct security_hook_list bpf_lsm_hooks[] __ro_after_init = {
10 #define LSM_HOOK(RET, DEFAULT, NAME, ...) \11 #define LSM_HOOK(RET, DEFAULT, NAME, ...) \
@@ -15,9 +16,15 @@ static struct security_hook_list bpf_lsm_hooks[] __ro_after_init = { · 4 unmodified lines
15 LSM_HOOK_INIT(task_free, bpf_task_storage_free),16 LSM_HOOK_INIT(task_free, bpf_task_storage_free),
16};17};
17 18
19static const struct lsm_id bpf_lsmid = {
20 .name = "bpf",
21 .id = LSM_ID_BPF,
22};
23
18static int __init bpf_lsm_init(void)24static int __init bpf_lsm_init(void)
19{25{
20 security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), "bpf");26 security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks),
27 &bpf_lsmid);
21 pr_info("LSM support for eBPF active\n");28 pr_info("LSM support for eBPF active\n");
22 return 0;29 return 0;
23}30}
security/commoncap.c+7−1
@@ -25,6 +25,7 @@ · 24 unmodified lines
25#include <linux/binfmts.h>25#include <linux/binfmts.h>
26#include <linux/personality.h>26#include <linux/personality.h>
27#include <linux/mnt_idmapping.h>27#include <linux/mnt_idmapping.h>
28#include <uapi/linux/lsm.h>
28 29
29/*30/*
30 * If a non-root user executes a setuid-root binary in31 * If a non-root user executes a setuid-root binary in
@@ -1440,6 +1441,11 @@ int cap_mmap_file(struct file *file, unsigned long reqprot, · 1409 unmodified lines
1440 1441
1441#ifdef CONFIG_SECURITY1442#ifdef CONFIG_SECURITY
1442 1443
1444static const struct lsm_id capability_lsmid = {
1445 .name = "capability",
1446 .id = LSM_ID_CAPABILITY,
1447};
1448
1443static struct security_hook_list capability_hooks[] __ro_after_init = {1449static struct security_hook_list capability_hooks[] __ro_after_init = {
1444 LSM_HOOK_INIT(capable, cap_capable),1450 LSM_HOOK_INIT(capable, cap_capable),
1445 LSM_HOOK_INIT(settime, cap_settime),1451 LSM_HOOK_INIT(settime, cap_settime),
@@ -1464,7 +1470,7 @@ static struct security_hook_list capability_hooks[] __ro_after_init = { · 18 unmodified lines
1464static int __init capability_init(void)1470static int __init capability_init(void)
1465{1471{
1466 security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks),1472 security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks),
1467 "capability");1473 &capability_lsmid);
1468 return 0;1474 return 0;
1469}1475}
1470 1476
security/landlock/cred.c+1−1
@@ -42,5 +42,5 @@ static struct security_hook_list landlock_hooks[] __ro_after_init = { · 41 unmodified lines
42__init void landlock_add_cred_hooks(void)42__init void landlock_add_cred_hooks(void)
43{43{
44 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),44 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
45 LANDLOCK_NAME);45 &landlock_lsmid);
46}46}
security/landlock/fs.c+1−1
@@ -1223,5 +1223,5 @@ static struct security_hook_list landlock_hooks[] __ro_after_init = { · 1222 unmodified lines
1223__init void landlock_add_fs_hooks(void)1223__init void landlock_add_fs_hooks(void)
1224{1224{
1225 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),1225 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
1226 LANDLOCK_NAME);1226 &landlock_lsmid);
1227}1227}
security/landlock/net.c+1−1
@@ -196,5 +196,5 @@ static struct security_hook_list landlock_hooks[] __ro_after_init = { · 195 unmodified lines
196__init void landlock_add_net_hooks(void)196__init void landlock_add_net_hooks(void)
197{197{
198 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),198 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
199 LANDLOCK_NAME);199 &landlock_lsmid);
200}200}
security/landlock/ptrace.c+1−1
@@ -116,5 +116,5 @@ static struct security_hook_list landlock_hooks[] __ro_after_init = { · 115 unmodified lines
116__init void landlock_add_ptrace_hooks(void)116__init void landlock_add_ptrace_hooks(void)
117{117{
118 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),118 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
119 LANDLOCK_NAME);119 &landlock_lsmid);
120}120}
security/landlock/setup.c+6−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
8 8
9#include <linux/init.h>9#include <linux/init.h>
10#include <linux/lsm_hooks.h>10#include <linux/lsm_hooks.h>
11#include <uapi/linux/lsm.h>
11 12
12#include "common.h"13#include "common.h"
13#include "cred.h"14#include "cred.h"
@@ -25,6 +26,11 @@ struct lsm_blob_sizes landlock_blob_sizes __ro_after_init = { · 11 unmodified lines
25 .lbs_superblock = sizeof(struct landlock_superblock_security),26 .lbs_superblock = sizeof(struct landlock_superblock_security),
26};27};
27 28
29const struct lsm_id landlock_lsmid = {
30 .name = LANDLOCK_NAME,
31 .id = LSM_ID_LANDLOCK,
32};
33
28static int __init landlock_init(void)34static int __init landlock_init(void)
29{35{
30 landlock_add_cred_hooks();36 landlock_add_cred_hooks();
security/landlock/setup.h+1−0
@@ -14,5 +14,6 @@ · 13 unmodified lines
14extern bool landlock_initialized;14extern bool landlock_initialized;
15 15
16extern struct lsm_blob_sizes landlock_blob_sizes;16extern struct lsm_blob_sizes landlock_blob_sizes;
17extern const struct lsm_id landlock_lsmid;
17 18
18#endif /* _SECURITY_LANDLOCK_SETUP_H */19#endif /* _SECURITY_LANDLOCK_SETUP_H */
security/loadpin/loadpin.c+8−1
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#include <linux/string_helpers.h>20#include <linux/string_helpers.h>
21#include <linux/dm-verity-loadpin.h>21#include <linux/dm-verity-loadpin.h>
22#include <uapi/linux/loadpin.h>22#include <uapi/linux/loadpin.h>
23#include <uapi/linux/lsm.h>
23 24
24#define VERITY_DIGEST_FILE_HEADER "# LOADPIN_TRUSTED_VERITY_ROOT_DIGESTS"25#define VERITY_DIGEST_FILE_HEADER "# LOADPIN_TRUSTED_VERITY_ROOT_DIGESTS"
25 26
@@ -208,6 +209,11 @@ static int loadpin_load_data(enum kernel_load_data_id id, bool contents) · 182 unmodified lines
208 return loadpin_check(NULL, (enum kernel_read_file_id) id);209 return loadpin_check(NULL, (enum kernel_read_file_id) id);
209}210}
210 211
212static const struct lsm_id loadpin_lsmid = {
213 .name = "loadpin",
214 .id = LSM_ID_LOADPIN,
215};
216
211static struct security_hook_list loadpin_hooks[] __ro_after_init = {217static struct security_hook_list loadpin_hooks[] __ro_after_init = {
212 LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security),218 LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security),
213 LSM_HOOK_INIT(kernel_read_file, loadpin_read_file),219 LSM_HOOK_INIT(kernel_read_file, loadpin_read_file),
@@ -259,7 +265,8 @@ static int __init loadpin_init(void) · 45 unmodified lines
259 if (!register_sysctl("kernel/loadpin", loadpin_sysctl_table))265 if (!register_sysctl("kernel/loadpin", loadpin_sysctl_table))
260 pr_notice("sysctl registration failed!\n");266 pr_notice("sysctl registration failed!\n");
261#endif267#endif
262 security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin");268 security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks),
269 &loadpin_lsmid);
263 270
264 return 0;271 return 0;
265}272}
security/lockdown/lockdown.c+7−1
@@ -13,6 +13,7 @@ · 12 unmodified lines
13#include <linux/security.h>13#include <linux/security.h>
14#include <linux/export.h>14#include <linux/export.h>
15#include <linux/lsm_hooks.h>15#include <linux/lsm_hooks.h>
16#include <uapi/linux/lsm.h>
16 17
17static enum lockdown_reason kernel_locked_down;18static enum lockdown_reason kernel_locked_down;
18 19
@@ -75,6 +76,11 @@ static struct security_hook_list lockdown_hooks[] __ro_after_init = { · 56 unmodified lines
75 LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),76 LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),
76};77};
77 78
79const struct lsm_id lockdown_lsmid = {
80 .name = "lockdown",
81 .id = LSM_ID_LOCKDOWN,
82};
83
78static int __init lockdown_lsm_init(void)84static int __init lockdown_lsm_init(void)
79{85{
80#if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY)86#if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY)
@@ -83,7 +89,7 @@ static int __init lockdown_lsm_init(void) · 2 unmodified lines
83 lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX);89 lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX);
84#endif90#endif
85 security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks),91 security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks),
86 "lockdown");92 &lockdown_lsmid);
87 return 0;93 return 0;
88}94}
89 95
security/lsm_syscalls.c+120−0
@@ -0,0 +1,120 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * System calls implementing the Linux Security Module API.
4 *
5 * Copyright (C) 2022 Casey Schaufler <casey@schaufler-ca.com>
6 * Copyright (C) 2022 Intel Corporation
7 */
8
9#include <asm/current.h>
10#include <linux/compiler_types.h>
11#include <linux/err.h>
12#include <linux/errno.h>
13#include <linux/security.h>
14#include <linux/stddef.h>
15#include <linux/syscalls.h>
16#include <linux/types.h>
17#include <linux/lsm_hooks.h>
18#include <uapi/linux/lsm.h>
19
20/**
21 * lsm_name_to_attr - map an LSM attribute name to its ID
22 * @name: name of the attribute
23 *
24 * Returns the LSM attribute value associated with @name, or 0 if
25 * there is no mapping.
26 */
27u64 lsm_name_to_attr(const char *name)
28{
29 if (!strcmp(name, "current"))
30 return LSM_ATTR_CURRENT;
31 if (!strcmp(name, "exec"))
32 return LSM_ATTR_EXEC;
33 if (!strcmp(name, "fscreate"))
34 return LSM_ATTR_FSCREATE;
35 if (!strcmp(name, "keycreate"))
36 return LSM_ATTR_KEYCREATE;
37 if (!strcmp(name, "prev"))
38 return LSM_ATTR_PREV;
39 if (!strcmp(name, "sockcreate"))
40 return LSM_ATTR_SOCKCREATE;
41 return LSM_ATTR_UNDEF;
42}
43
44/**
45 * sys_lsm_set_self_attr - Set current task's security module attribute
46 * @attr: which attribute to set
47 * @ctx: the LSM contexts
48 * @size: size of @ctx
49 * @flags: reserved for future use
50 *
51 * Sets the calling task's LSM context. On success this function
52 * returns 0. If the attribute specified cannot be set a negative
53 * value indicating the reason for the error is returned.
54 */
55SYSCALL_DEFINE4(lsm_set_self_attr, unsigned int, attr, struct lsm_ctx __user *,
56 ctx, size_t, size, u32, flags)
57{
58 return security_setselfattr(attr, ctx, size, flags);
59}
60
61/**
62 * sys_lsm_get_self_attr - Return current task's security module attributes
63 * @attr: which attribute to return
64 * @ctx: the user-space destination for the information, or NULL
65 * @size: pointer to the size of space available to receive the data
66 * @flags: special handling options. LSM_FLAG_SINGLE indicates that only
67 * attributes associated with the LSM identified in the passed @ctx be
68 * reported.
69 *
70 * Returns the calling task's LSM contexts. On success this
71 * function returns the number of @ctx array elements. This value
72 * may be zero if there are no LSM contexts assigned. If @size is
73 * insufficient to contain the return data -E2BIG is returned and
74 * @size is set to the minimum required size. In all other cases
75 * a negative value indicating the error is returned.
76 */
77SYSCALL_DEFINE4(lsm_get_self_attr, unsigned int, attr, struct lsm_ctx __user *,
78 ctx, size_t __user *, size, u32, flags)
79{
80 return security_getselfattr(attr, ctx, size, flags);
81}
82
83/**
84 * sys_lsm_list_modules - Return a list of the active security modules
85 * @ids: the LSM module ids
86 * @size: pointer to size of @ids, updated on return
87 * @flags: reserved for future use, must be zero
88 *
89 * Returns a list of the active LSM ids. On success this function
90 * returns the number of @ids array elements. This value may be zero
91 * if there are no LSMs active. If @size is insufficient to contain
92 * the return data -E2BIG is returned and @size is set to the minimum
93 * required size. In all other cases a negative value indicating the
94 * error is returned.
95 */
96SYSCALL_DEFINE3(lsm_list_modules, u64 __user *, ids, size_t __user *, size,
97 u32, flags)
98{
99 size_t total_size = lsm_active_cnt * sizeof(*ids);
100 size_t usize;
101 int i;
102
103 if (flags)
104 return -EINVAL;
105
106 if (get_user(usize, size))
107 return -EFAULT;
108
109 if (put_user(total_size, size) != 0)
110 return -EFAULT;
111
112 if (usize < total_size)
113 return -E2BIG;
114
115 for (i = 0; i < lsm_active_cnt; i++)
116 if (put_user(lsm_idlist[i]->id, ids++))
117 return -EFAULT;
118
119 return lsm_active_cnt;
120}
security/safesetid/lsm.c+8−1
@@ -19,6 +19,7 @@ · 18 unmodified lines
19#include <linux/ptrace.h>19#include <linux/ptrace.h>
20#include <linux/sched/task_stack.h>20#include <linux/sched/task_stack.h>
21#include <linux/security.h>21#include <linux/security.h>
22#include <uapi/linux/lsm.h>
22#include "lsm.h"23#include "lsm.h"
23 24
24/* Flag indicating whether initialization completed */25/* Flag indicating whether initialization completed */
@@ -261,6 +262,11 @@ static int safesetid_task_fix_setgroups(struct cred *new, const struct cred *old · 236 unmodified lines
261 return 0;262 return 0;
262}263}
263 264
265static const struct lsm_id safesetid_lsmid = {
266 .name = "safesetid",
267 .id = LSM_ID_SAFESETID,
268};
269
264static struct security_hook_list safesetid_security_hooks[] = {270static struct security_hook_list safesetid_security_hooks[] = {
265 LSM_HOOK_INIT(task_fix_setuid, safesetid_task_fix_setuid),271 LSM_HOOK_INIT(task_fix_setuid, safesetid_task_fix_setuid),
266 LSM_HOOK_INIT(task_fix_setgid, safesetid_task_fix_setgid),272 LSM_HOOK_INIT(task_fix_setgid, safesetid_task_fix_setgid),
@@ -271,7 +277,8 @@ static struct security_hook_list safesetid_security_hooks[] = { · 4 unmodified lines
271static int __init safesetid_security_init(void)277static int __init safesetid_security_init(void)
272{278{
273 security_add_hooks(safesetid_security_hooks,279 security_add_hooks(safesetid_security_hooks,
274 ARRAY_SIZE(safesetid_security_hooks), "safesetid");280 ARRAY_SIZE(safesetid_security_hooks),
281 &safesetid_lsmid);
275 282
276 /* Report that SafeSetID successfully initialized */283 /* Report that SafeSetID successfully initialized */
277 safesetid_initialized = 1;284 safesetid_initialized = 1;
security/security.c+261−12
@@ -34,6 +34,24 @@ · 33 unmodified lines
34/* How many LSMs were built into the kernel? */34/* How many LSMs were built into the kernel? */
35#define LSM_COUNT (__end_lsm_info - __start_lsm_info)35#define LSM_COUNT (__end_lsm_info - __start_lsm_info)
36 36
37/*
38 * How many LSMs are built into the kernel as determined at
39 * build time. Used to determine fixed array sizes.
40 * The capability module is accounted for by CONFIG_SECURITY
41 */
42#define LSM_CONFIG_COUNT ( \
43 (IS_ENABLED(CONFIG_SECURITY) ? 1 : 0) + \
44 (IS_ENABLED(CONFIG_SECURITY_SELINUX) ? 1 : 0) + \
45 (IS_ENABLED(CONFIG_SECURITY_SMACK) ? 1 : 0) + \
46 (IS_ENABLED(CONFIG_SECURITY_TOMOYO) ? 1 : 0) + \
47 (IS_ENABLED(CONFIG_SECURITY_APPARMOR) ? 1 : 0) + \
48 (IS_ENABLED(CONFIG_SECURITY_YAMA) ? 1 : 0) + \
49 (IS_ENABLED(CONFIG_SECURITY_LOADPIN) ? 1 : 0) + \
50 (IS_ENABLED(CONFIG_SECURITY_SAFESETID) ? 1 : 0) + \
51 (IS_ENABLED(CONFIG_SECURITY_LOCKDOWN_LSM) ? 1 : 0) + \
52 (IS_ENABLED(CONFIG_BPF_LSM) ? 1 : 0) + \
53 (IS_ENABLED(CONFIG_SECURITY_LANDLOCK) ? 1 : 0))
54
37/*55/*
38 * These are descriptions of the reasons that can be passed to the56 * These are descriptions of the reasons that can be passed to the
39 * security_locked_down() LSM hook. Placing this array here allows57 * security_locked_down() LSM hook. Placing this array here allows
@@ -245,6 +263,12 @@ static void __init initialize_lsm(struct lsm_info *lsm) · 205 unmodified lines
245 }263 }
246}264}
247 265
266/*
267 * Current index to use while initializing the lsm id list.
268 */
269u32 lsm_active_cnt __ro_after_init;
270const struct lsm_id *lsm_idlist[LSM_CONFIG_COUNT];
271
248/* Populate ordered LSMs list from comma-separated LSM name list. */272/* Populate ordered LSMs list from comma-separated LSM name list. */
249static void __init ordered_lsm_parse(const char *order, const char *origin)273static void __init ordered_lsm_parse(const char *order, const char *origin)
250{274{
@@ -513,17 +537,29 @@ static int lsm_append(const char *new, char **result) · 262 unmodified lines
513 * security_add_hooks - Add a modules hooks to the hook lists.537 * security_add_hooks - Add a modules hooks to the hook lists.
514 * @hooks: the hooks to add538 * @hooks: the hooks to add
515 * @count: the number of hooks to add539 * @count: the number of hooks to add
516 * @lsm: the name of the security module540 * @lsmid: the identification information for the security module
517 *541 *
518 * Each LSM has to register its hooks with the infrastructure.542 * Each LSM has to register its hooks with the infrastructure.
519 */543 */
520void __init security_add_hooks(struct security_hook_list *hooks, int count,544void __init security_add_hooks(struct security_hook_list *hooks, int count,
521 const char *lsm)545 const struct lsm_id *lsmid)
522{546{
523 int i;547 int i;
524 548
549 /*
550 * A security module may call security_add_hooks() more
551 * than once during initialization, and LSM initialization
552 * is serialized. Landlock is one such case.
553 * Look at the previous entry, if there is one, for duplication.
554 */
555 if (lsm_active_cnt == 0 || lsm_idlist[lsm_active_cnt - 1] != lsmid) {
556 if (lsm_active_cnt >= LSM_CONFIG_COUNT)
557 panic("%s Too many LSMs registered.\n", __func__);
558 lsm_idlist[lsm_active_cnt++] = lsmid;
559 }
560
525 for (i = 0; i < count; i++) {561 for (i = 0; i < count; i++) {
526 hooks[i].lsm = lsm;562 hooks[i].lsmid = lsmid;
527 hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);563 hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
528 }564 }
529 565
@@ -532,7 +568,7 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count, · 2 unmodified lines
532 * and fix this up afterwards.568 * and fix this up afterwards.
533 */569 */
534 if (slab_is_available()) {570 if (slab_is_available()) {
535 if (lsm_append(lsm, &lsm_names) < 0)571 if (lsm_append(lsmid->name, &lsm_names) < 0)
536 panic("%s - Cannot get early memory.\n", __func__);572 panic("%s - Cannot get early memory.\n", __func__);
537 }573 }
538}574}
@@ -734,6 +770,54 @@ static int lsm_superblock_alloc(struct super_block *sb) · 195 unmodified lines
734 return 0;770 return 0;
735}771}
736 772
773/**
774 * lsm_fill_user_ctx - Fill a user space lsm_ctx structure
775 * @uctx: a userspace LSM context to be filled
776 * @uctx_len: available uctx size (input), used uctx size (output)
777 * @val: the new LSM context value
778 * @val_len: the size of the new LSM context value
779 * @id: LSM id
780 * @flags: LSM defined flags
781 *
782 * Fill all of the fields in a userspace lsm_ctx structure.
783 *
784 * Returns 0 on success, -E2BIG if userspace buffer is not large enough,
785 * -EFAULT on a copyout error, -ENOMEM if memory can't be allocated.
786 */
787int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, size_t *uctx_len,
788 void *val, size_t val_len,
789 u64 id, u64 flags)
790{
791 struct lsm_ctx *nctx = NULL;
792 size_t nctx_len;
793 int rc = 0;
794
795 nctx_len = ALIGN(struct_size(nctx, ctx, val_len), sizeof(void *));
796 if (nctx_len > *uctx_len) {
797 rc = -E2BIG;
798 goto out;
799 }
800
801 nctx = kzalloc(nctx_len, GFP_KERNEL);
802 if (nctx == NULL) {
803 rc = -ENOMEM;
804 goto out;
805 }
806 nctx->id = id;
807 nctx->flags = flags;
808 nctx->len = nctx_len;
809 nctx->ctx_len = val_len;
810 memcpy(nctx->ctx, val, val_len);
811
812 if (copy_to_user(uctx, nctx, nctx_len))
813 rc = -EFAULT;
814
815out:
816 kfree(nctx);
817 *uctx_len = nctx_len;
818 return rc;
819}
820
737/*821/*
738 * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and822 * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and
739 * can be accessed with:823 * can be accessed with:
@@ -2642,6 +2726,24 @@ int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 1902 unmodified lines
2642}2726}
2643EXPORT_SYMBOL_GPL(security_file_ioctl);2727EXPORT_SYMBOL_GPL(security_file_ioctl);
2644 2728
2729/**
2730 * security_file_ioctl_compat() - Check if an ioctl is allowed in compat mode
2731 * @file: associated file
2732 * @cmd: ioctl cmd
2733 * @arg: ioctl arguments
2734 *
2735 * Compat version of security_file_ioctl() that correctly handles 32-bit
2736 * processes running on 64-bit kernels.
2737 *
2738 * Return: Returns 0 if permission is granted.
2739 */
2740int security_file_ioctl_compat(struct file *file, unsigned int cmd,
2741 unsigned long arg)
2742{
2743 return call_int_hook(file_ioctl_compat, 0, file, cmd, arg);
2744}
2745EXPORT_SYMBOL_GPL(security_file_ioctl_compat);
2746
2645static inline unsigned long mmap_prot(struct file *file, unsigned long prot)2747static inline unsigned long mmap_prot(struct file *file, unsigned long prot)
2646{2748{
2647 /*2749 /*
@@ -3794,10 +3896,158 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode) · 1146 unmodified lines
3794}3896}
3795EXPORT_SYMBOL(security_d_instantiate);3897EXPORT_SYMBOL(security_d_instantiate);
3796 3898
3899/*
3900 * Please keep this in sync with it's counterpart in security/lsm_syscalls.c
3901 */
3902
3903/**
3904 * security_getselfattr - Read an LSM attribute of the current process.
3905 * @attr: which attribute to return
3906 * @uctx: the user-space destination for the information, or NULL
3907 * @size: pointer to the size of space available to receive the data
3908 * @flags: special handling options. LSM_FLAG_SINGLE indicates that only
3909 * attributes associated with the LSM identified in the passed @ctx be
3910 * reported.
3911 *
3912 * A NULL value for @uctx can be used to get both the number of attributes
3913 * and the size of the data.
3914 *
3915 * Returns the number of attributes found on success, negative value
3916 * on error. @size is reset to the total size of the data.
3917 * If @size is insufficient to contain the data -E2BIG is returned.
3918 */
3919int security_getselfattr(unsigned int attr, struct lsm_ctx __user *uctx,
3920 size_t __user *size, u32 flags)
3921{
3922 struct security_hook_list *hp;
3923 struct lsm_ctx lctx = { .id = LSM_ID_UNDEF, };
3924 u8 __user *base = (u8 __user *)uctx;
3925 size_t total = 0;
3926 size_t entrysize;
3927 size_t left;
3928 bool toobig = false;
3929 bool single = false;
3930 int count = 0;
3931 int rc;
3932
3933 if (attr == LSM_ATTR_UNDEF)
3934 return -EINVAL;
3935 if (size == NULL)
3936 return -EINVAL;
3937 if (get_user(left, size))
3938 return -EFAULT;
3939
3940 if (flags) {
3941 /*
3942 * Only flag supported is LSM_FLAG_SINGLE
3943 */
3944 if (flags != LSM_FLAG_SINGLE || !uctx)
3945 return -EINVAL;
3946 if (copy_from_user(&lctx, uctx, sizeof(lctx)))
3947 return -EFAULT;
3948 /*
3949 * If the LSM ID isn't specified it is an error.
3950 */
3951 if (lctx.id == LSM_ID_UNDEF)
3952 return -EINVAL;
3953 single = true;
3954 }
3955
3956 /*
3957 * In the usual case gather all the data from the LSMs.
3958 * In the single case only get the data from the LSM specified.
3959 */
3960 hlist_for_each_entry(hp, &security_hook_heads.getselfattr, list) {
3961 if (single && lctx.id != hp->lsmid->id)
3962 continue;
3963 entrysize = left;
3964 if (base)
3965 uctx = (struct lsm_ctx __user *)(base + total);
3966 rc = hp->hook.getselfattr(attr, uctx, &entrysize, flags);
3967 if (rc == -EOPNOTSUPP) {
3968 rc = 0;
3969 continue;
3970 }
3971 if (rc == -E2BIG) {
3972 rc = 0;
3973 left = 0;
3974 toobig = true;
3975 } else if (rc < 0)
3976 return rc;
3977 else
3978 left -= entrysize;
3979
3980 total += entrysize;
3981 count += rc;
3982 if (single)
3983 break;
3984 }
3985 if (put_user(total, size))
3986 return -EFAULT;
3987 if (toobig)
3988 return -E2BIG;
3989 if (count == 0)
3990 return LSM_RET_DEFAULT(getselfattr);
3991 return count;
3992}
3993
3994/*
3995 * Please keep this in sync with it's counterpart in security/lsm_syscalls.c
3996 */
3997
3998/**
3999 * security_setselfattr - Set an LSM attribute on the current process.
4000 * @attr: which attribute to set
4001 * @uctx: the user-space source for the information
4002 * @size: the size of the data
4003 * @flags: reserved for future use, must be 0
4004 *
4005 * Set an LSM attribute for the current process. The LSM, attribute
4006 * and new value are included in @uctx.
4007 *
4008 * Returns 0 on success, -EINVAL if the input is inconsistent, -EFAULT
4009 * if the user buffer is inaccessible, E2BIG if size is too big, or an
4010 * LSM specific failure.
4011 */
4012int security_setselfattr(unsigned int attr, struct lsm_ctx __user *uctx,
4013 size_t size, u32 flags)
4014{
4015 struct security_hook_list *hp;
4016 struct lsm_ctx *lctx;
4017 int rc = LSM_RET_DEFAULT(setselfattr);
4018
4019 if (flags)
4020 return -EINVAL;
4021 if (size < sizeof(*lctx))
4022 return -EINVAL;
4023 if (size > PAGE_SIZE)
4024 return -E2BIG;
4025
4026 lctx = memdup_user(uctx, size);
4027 if (IS_ERR(lctx))
4028 return PTR_ERR(lctx);
4029
4030 if (size < lctx->len || size < lctx->ctx_len + sizeof(*lctx) ||
4031 lctx->len < lctx->ctx_len + sizeof(*lctx)) {
4032 rc = -EINVAL;
4033 goto free_out;
4034 }
4035
4036 hlist_for_each_entry(hp, &security_hook_heads.setselfattr, list)
4037 if ((hp->lsmid->id) == lctx->id) {
4038 rc = hp->hook.setselfattr(attr, lctx, size, flags);
4039 break;
4040 }
4041
4042free_out:
4043 kfree(lctx);
4044 return rc;
4045}
4046
3797/**4047/**
3798 * security_getprocattr() - Read an attribute for a task4048 * security_getprocattr() - Read an attribute for a task
3799 * @p: the task4049 * @p: the task
3800 * @lsm: LSM name4050 * @lsmid: LSM identification
3801 * @name: attribute name4051 * @name: attribute name
3802 * @value: attribute value4052 * @value: attribute value
3803 *4053 *
@@ -3805,13 +4055,13 @@ EXPORT_SYMBOL(security_d_instantiate); · 1 unmodified line
3805 *4055 *
3806 * Return: Returns the length of @value on success, a negative value otherwise.4056 * Return: Returns the length of @value on success, a negative value otherwise.
3807 */4057 */
3808int security_getprocattr(struct task_struct *p, const char *lsm,4058int security_getprocattr(struct task_struct *p, int lsmid, const char *name,
3809 const char *name, char **value)4059 char **value)
3810{4060{
3811 struct security_hook_list *hp;4061 struct security_hook_list *hp;
3812 4062
3813 hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) {4063 hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) {
3814 if (lsm != NULL && strcmp(lsm, hp->lsm))4064 if (lsmid != 0 && lsmid != hp->lsmid->id)
3815 continue;4065 continue;
3816 return hp->hook.getprocattr(p, name, value);4066 return hp->hook.getprocattr(p, name, value);
3817 }4067 }
@@ -3820,7 +4070,7 @@ int security_getprocattr(struct task_struct *p, const char *lsm, · 2 unmodified lines
3820 4070
3821/**4071/**
3822 * security_setprocattr() - Set an attribute for a task4072 * security_setprocattr() - Set an attribute for a task
3823 * @lsm: LSM name4073 * @lsmid: LSM identification
3824 * @name: attribute name4074 * @name: attribute name
3825 * @value: attribute value4075 * @value: attribute value
3826 * @size: attribute value size4076 * @size: attribute value size
@@ -3830,13 +4080,12 @@ int security_getprocattr(struct task_struct *p, const char *lsm, · 3 unmodified lines
3830 *4080 *
3831 * Return: Returns bytes written on success, a negative value otherwise.4081 * Return: Returns bytes written on success, a negative value otherwise.
3832 */4082 */
3833int security_setprocattr(const char *lsm, const char *name, void *value,4083int security_setprocattr(int lsmid, const char *name, void *value, size_t size)
3834 size_t size)
3835{4084{
3836 struct security_hook_list *hp;4085 struct security_hook_list *hp;
3837 4086
3838 hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) {4087 hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) {
3839 if (lsm != NULL && strcmp(lsm, hp->lsm))4088 if (lsmid != 0 && lsmid != hp->lsmid->id)
3840 continue;4089 continue;
3841 return hp->hook.setprocattr(name, value, size);4090 return hp->hook.setprocattr(name, value, size);
3842 }4091 }
security/selinux/hooks.c+145−28
@@ -92,6 +92,7 @@ · 91 unmodified lines
92#include <linux/fsnotify.h>92#include <linux/fsnotify.h>
93#include <linux/fanotify.h>93#include <linux/fanotify.h>
94#include <linux/io_uring.h>94#include <linux/io_uring.h>
95#include <uapi/linux/lsm.h>
95 96
96#include "avc.h"97#include "avc.h"
97#include "objsec.h"98#include "objsec.h"
@@ -3738,6 +3739,33 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, · 3640 unmodified lines
3738 return error;3739 return error;
3739}3740}
3740 3741
3742static int selinux_file_ioctl_compat(struct file *file, unsigned int cmd,
3743 unsigned long arg)
3744{
3745 /*
3746 * If we are in a 64-bit kernel running 32-bit userspace, we need to
3747 * make sure we don't compare 32-bit flags to 64-bit flags.
3748 */
3749 switch (cmd) {
3750 case FS_IOC32_GETFLAGS:
3751 cmd = FS_IOC_GETFLAGS;
3752 break;
3753 case FS_IOC32_SETFLAGS:
3754 cmd = FS_IOC_SETFLAGS;
3755 break;
3756 case FS_IOC32_GETVERSION:
3757 cmd = FS_IOC_GETVERSION;
3758 break;
3759 case FS_IOC32_SETVERSION:
3760 cmd = FS_IOC_SETVERSION;
3761 break;
3762 default:
3763 break;
3764 }
3765
3766 return selinux_file_ioctl(file, cmd, arg);
3767}
3768
3741static int default_noexec __ro_after_init;3769static int default_noexec __ro_after_init;
3742 3770
3743static int file_map_prot_check(struct file *file, unsigned long prot, int shared)3771static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
@@ -6313,8 +6341,8 @@ static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode) · 2569 unmodified lines
6313 inode_doinit_with_dentry(inode, dentry);6341 inode_doinit_with_dentry(inode, dentry);
6314}6342}
6315 6343
6316static int selinux_getprocattr(struct task_struct *p,6344static int selinux_lsm_getattr(unsigned int attr, struct task_struct *p,
6317 const char *name, char **value)6345 char **value)
6318{6346{
6319 const struct task_security_struct *__tsec;6347 const struct task_security_struct *__tsec;
6320 u32 sid;6348 u32 sid;
@@ -6331,20 +6359,27 @@ static int selinux_getprocattr(struct task_struct *p, · 10 unmodified lines
6331 goto bad;6359 goto bad;
6332 }6360 }
6333 6361
6334 if (!strcmp(name, "current"))6362 switch (attr) {
6363 case LSM_ATTR_CURRENT:
6335 sid = __tsec->sid;6364 sid = __tsec->sid;
6336 else if (!strcmp(name, "prev"))6365 break;
6366 case LSM_ATTR_PREV:
6337 sid = __tsec->osid;6367 sid = __tsec->osid;
6338 else if (!strcmp(name, "exec"))6368 break;
6369 case LSM_ATTR_EXEC:
6339 sid = __tsec->exec_sid;6370 sid = __tsec->exec_sid;
6340 else if (!strcmp(name, "fscreate"))6371 break;
6372 case LSM_ATTR_FSCREATE:
6341 sid = __tsec->create_sid;6373 sid = __tsec->create_sid;
6342 else if (!strcmp(name, "keycreate"))6374 break;
6375 case LSM_ATTR_KEYCREATE:
6343 sid = __tsec->keycreate_sid;6376 sid = __tsec->keycreate_sid;
6344 else if (!strcmp(name, "sockcreate"))6377 break;
6378 case LSM_ATTR_SOCKCREATE:
6345 sid = __tsec->sockcreate_sid;6379 sid = __tsec->sockcreate_sid;
6346 else {6380 break;
6347 error = -EINVAL;6381 default:
6382 error = -EOPNOTSUPP;
6348 goto bad;6383 goto bad;
6349 }6384 }
6350 rcu_read_unlock();6385 rcu_read_unlock();
@@ -6362,7 +6397,7 @@ bad: · 11 unmodified lines
6362 return error;6397 return error;
6363}6398}
6364 6399
6365static int selinux_setprocattr(const char *name, void *value, size_t size)6400static int selinux_lsm_setattr(u64 attr, void *value, size_t size)
6366{6401{
6367 struct task_security_struct *tsec;6402 struct task_security_struct *tsec;
6368 struct cred *new;6403 struct cred *new;
@@ -6373,23 +6408,31 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) · 4 unmodified lines
6373 /*6408 /*
6374 * Basic control over ability to set these attributes at all.6409 * Basic control over ability to set these attributes at all.
6375 */6410 */
6376 if (!strcmp(name, "exec"))6411 switch (attr) {
6412 case LSM_ATTR_EXEC:
6377 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,6413 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
6378 PROCESS__SETEXEC, NULL);6414 PROCESS__SETEXEC, NULL);
6379 else if (!strcmp(name, "fscreate"))6415 break;
6416 case LSM_ATTR_FSCREATE:
6380 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,6417 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
6381 PROCESS__SETFSCREATE, NULL);6418 PROCESS__SETFSCREATE, NULL);
6382 else if (!strcmp(name, "keycreate"))6419 break;
6420 case LSM_ATTR_KEYCREATE:
6383 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,6421 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
6384 PROCESS__SETKEYCREATE, NULL);6422 PROCESS__SETKEYCREATE, NULL);
6385 else if (!strcmp(name, "sockcreate"))6423 break;
6424 case LSM_ATTR_SOCKCREATE:
6386 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,6425 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
6387 PROCESS__SETSOCKCREATE, NULL);6426 PROCESS__SETSOCKCREATE, NULL);
6388 else if (!strcmp(name, "current"))6427 break;
6428 case LSM_ATTR_CURRENT:
6389 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,6429 error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
6390 PROCESS__SETCURRENT, NULL);6430 PROCESS__SETCURRENT, NULL);
6391 else6431 break;
6392 error = -EINVAL;6432 default:
6433 error = -EOPNOTSUPP;
6434 break;
6435 }
6393 if (error)6436 if (error)
6394 return error;6437 return error;
6395 6438
@@ -6401,13 +6444,14 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) · 5 unmodified lines
6401 }6444 }
6402 error = security_context_to_sid(value, size,6445 error = security_context_to_sid(value, size,
6403 &sid, GFP_KERNEL);6446 &sid, GFP_KERNEL);
6404 if (error == -EINVAL && !strcmp(name, "fscreate")) {6447 if (error == -EINVAL && attr == LSM_ATTR_FSCREATE) {
6405 if (!has_cap_mac_admin(true)) {6448 if (!has_cap_mac_admin(true)) {
6406 struct audit_buffer *ab;6449 struct audit_buffer *ab;
6407 size_t audit_size;6450 size_t audit_size;
6408 6451
6409 /* We strip a nul only if it is at the end, otherwise the6452 /* We strip a nul only if it is at the end,
6410 * context contains a nul and we should audit that */6453 * otherwise the context contains a nul and
6454 * we should audit that */
6411 if (str[size - 1] == '\0')6455 if (str[size - 1] == '\0')
6412 audit_size = size - 1;6456 audit_size = size - 1;
6413 else6457 else
@@ -6418,7 +6462,8 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) · 4 unmodified lines
6418 if (!ab)6462 if (!ab)
6419 return error;6463 return error;
6420 audit_log_format(ab, "op=fscreate invalid_context=");6464 audit_log_format(ab, "op=fscreate invalid_context=");
6421 audit_log_n_untrustedstring(ab, value, audit_size);6465 audit_log_n_untrustedstring(ab, value,
6466 audit_size);
6422 audit_log_end(ab);6467 audit_log_end(ab);
6423 6468
6424 return error;6469 return error;
@@ -6441,11 +6486,11 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) · 16 unmodified lines
6441 checks and may_create for the file creation checks. The6486 checks and may_create for the file creation checks. The
6442 operation will then fail if the context is not permitted. */6487 operation will then fail if the context is not permitted. */
6443 tsec = selinux_cred(new);6488 tsec = selinux_cred(new);
6444 if (!strcmp(name, "exec")) {6489 if (attr == LSM_ATTR_EXEC) {
6445 tsec->exec_sid = sid;6490 tsec->exec_sid = sid;
6446 } else if (!strcmp(name, "fscreate")) {6491 } else if (attr == LSM_ATTR_FSCREATE) {
6447 tsec->create_sid = sid;6492 tsec->create_sid = sid;
6448 } else if (!strcmp(name, "keycreate")) {6493 } else if (attr == LSM_ATTR_KEYCREATE) {
6449 if (sid) {6494 if (sid) {
6450 error = avc_has_perm(mysid, sid,6495 error = avc_has_perm(mysid, sid,
6451 SECCLASS_KEY, KEY__CREATE, NULL);6496 SECCLASS_KEY, KEY__CREATE, NULL);
@@ -6453,9 +6498,9 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) · 1 unmodified line
6453 goto abort_change;6498 goto abort_change;
6454 }6499 }
6455 tsec->keycreate_sid = sid;6500 tsec->keycreate_sid = sid;
6456 } else if (!strcmp(name, "sockcreate")) {6501 } else if (attr == LSM_ATTR_SOCKCREATE) {
6457 tsec->sockcreate_sid = sid;6502 tsec->sockcreate_sid = sid;
6458 } else if (!strcmp(name, "current")) {6503 } else if (attr == LSM_ATTR_CURRENT) {
6459 error = -EINVAL;6504 error = -EINVAL;
6460 if (sid == 0)6505 if (sid == 0)
6461 goto abort_change;6506 goto abort_change;
@@ -6496,6 +6541,69 @@ abort_change: · 34 unmodified lines
6496 return error;6541 return error;
6497}6542}
6498 6543
6544/**
6545 * selinux_getselfattr - Get SELinux current task attributes
6546 * @attr: the requested attribute
6547 * @ctx: buffer to receive the result
6548 * @size: buffer size (input), buffer size used (output)
6549 * @flags: unused
6550 *
6551 * Fill the passed user space @ctx with the details of the requested
6552 * attribute.
6553 *
6554 * Returns the number of attributes on success, an error code otherwise.
6555 * There will only ever be one attribute.
6556 */
6557static int selinux_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
6558 size_t *size, u32 flags)
6559{
6560 int rc;
6561 char *val;
6562 int val_len;
6563
6564 val_len = selinux_lsm_getattr(attr, current, &val);
6565 if (val_len < 0)
6566 return val_len;
6567 rc = lsm_fill_user_ctx(ctx, size, val, val_len, LSM_ID_SELINUX, 0);
6568 kfree(val);
6569 return (!rc ? 1 : rc);
6570}
6571
6572static int selinux_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
6573 size_t size, u32 flags)
6574{
6575 int rc;
6576
6577 rc = selinux_lsm_setattr(attr, ctx->ctx, ctx->ctx_len);
6578 if (rc > 0)
6579 return 0;
6580 return rc;
6581}
6582
6583static int selinux_getprocattr(struct task_struct *p,
6584 const char *name, char **value)
6585{
6586 unsigned int attr = lsm_name_to_attr(name);
6587 int rc;
6588
6589 if (attr) {
6590 rc = selinux_lsm_getattr(attr, p, value);
6591 if (rc != -EOPNOTSUPP)
6592 return rc;
6593 }
6594
6595 return -EINVAL;
6596}
6597
6598static int selinux_setprocattr(const char *name, void *value, size_t size)
6599{
6600 int attr = lsm_name_to_attr(name);
6601
6602 if (attr)
6603 return selinux_lsm_setattr(attr, value, size);
6604 return -EINVAL;
6605}
6606
6499static int selinux_ismaclabel(const char *name)6607static int selinux_ismaclabel(const char *name)
6500{6608{
6501 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);6609 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
@@ -6978,6 +7086,11 @@ static int selinux_uring_cmd(struct io_uring_cmd *ioucmd) · 476 unmodified lines
6978}7086}
6979#endif /* CONFIG_IO_URING */7087#endif /* CONFIG_IO_URING */
6980 7088
7089static const struct lsm_id selinux_lsmid = {
7090 .name = "selinux",
7091 .id = LSM_ID_SELINUX,
7092};
7093
6981/*7094/*
6982 * IMPORTANT NOTE: When adding new hooks, please be careful to keep this order:7095 * IMPORTANT NOTE: When adding new hooks, please be careful to keep this order:
6983 * 1. any hooks that don't belong to (2.) or (3.) below,7096 * 1. any hooks that don't belong to (2.) or (3.) below,
@@ -7064,6 +7177,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = { · 80 unmodified lines
7064 LSM_HOOK_INIT(file_permission, selinux_file_permission),7177 LSM_HOOK_INIT(file_permission, selinux_file_permission),
7065 LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),7178 LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
7066 LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),7179 LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
7180 LSM_HOOK_INIT(file_ioctl_compat, selinux_file_ioctl_compat),
7067 LSM_HOOK_INIT(mmap_file, selinux_mmap_file),7181 LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
7068 LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),7182 LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),
7069 LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),7183 LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
@@ -7119,6 +7233,8 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = { · 49 unmodified lines
7119 7233
7120 LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate),7234 LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate),
7121 7235
7236 LSM_HOOK_INIT(getselfattr, selinux_getselfattr),
7237 LSM_HOOK_INIT(setselfattr, selinux_setselfattr),
7122 LSM_HOOK_INIT(getprocattr, selinux_getprocattr),7238 LSM_HOOK_INIT(getprocattr, selinux_getprocattr),
7123 LSM_HOOK_INIT(setprocattr, selinux_setprocattr),7239 LSM_HOOK_INIT(setprocattr, selinux_setprocattr),
7124 7240
@@ -7298,7 +7414,8 @@ static __init int selinux_init(void) · 173 unmodified lines
7298 7414
7299 hashtab_cache_init();7415 hashtab_cache_init();
7300 7416
7301 security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");7417 security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks),
7418 &selinux_lsmid);
7302 7419
7303 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))7420 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
7304 panic("SELinux: Unable to register AVC netcache callback\n");7421 panic("SELinux: Unable to register AVC netcache callback\n");
security/smack/smack_lsm.c+87−6
@@ -43,6 +43,7 @@ · 42 unmodified lines
43#include <linux/fs_parser.h>43#include <linux/fs_parser.h>
44#include <linux/watch_queue.h>44#include <linux/watch_queue.h>
45#include <linux/io_uring.h>45#include <linux/io_uring.h>
46#include <uapi/linux/lsm.h>
46#include "smack.h"47#include "smack.h"
47 48
48#define TRANS_TRUE "TRUE"49#define TRANS_TRUE "TRUE"
@@ -3625,6 +3626,35 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) · 3576 unmodified lines
3625 return;3626 return;
3626}3627}
3627 3628
3629/**
3630 * smack_getselfattr - Smack current process attribute
3631 * @attr: which attribute to fetch
3632 * @ctx: buffer to receive the result
3633 * @size: available size in, actual size out
3634 * @flags: unused
3635 *
3636 * Fill the passed user space @ctx with the details of the requested
3637 * attribute.
3638 *
3639 * Returns the number of attributes on success, an error code otherwise.
3640 * There will only ever be one attribute.
3641 */
3642static int smack_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
3643 size_t *size, u32 flags)
3644{
3645 int rc;
3646 struct smack_known *skp;
3647
3648 if (attr != LSM_ATTR_CURRENT)
3649 return -EOPNOTSUPP;
3650
3651 skp = smk_of_current();
3652 rc = lsm_fill_user_ctx(ctx, size,
3653 skp->smk_known, strlen(skp->smk_known) + 1,
3654 LSM_ID_SMACK, 0);
3655 return (!rc ? 1 : rc);
3656}
3657
3628/**3658/**
3629 * smack_getprocattr - Smack process attribute access3659 * smack_getprocattr - Smack process attribute access
3630 * @p: the object task3660 * @p: the object task
@@ -3654,8 +3684,8 @@ static int smack_getprocattr(struct task_struct *p, const char *name, char **val · 23 unmodified lines
3654}3684}
3655 3685
3656/**3686/**
3657 * smack_setprocattr - Smack process attribute setting3687 * do_setattr - Smack process attribute setting
3658 * @name: the name of the attribute in /proc/.../attr3688 * @attr: the ID of the attribute
3659 * @value: the value to set3689 * @value: the value to set
3660 * @size: the size of the value3690 * @size: the size of the value
3661 *3691 *
@@ -3664,7 +3694,7 @@ static int smack_getprocattr(struct task_struct *p, const char *name, char **val · 2 unmodified lines
3664 *3694 *
3665 * Returns the length of the smack label or an error code3695 * Returns the length of the smack label or an error code
3666 */3696 */
3667static int smack_setprocattr(const char *name, void *value, size_t size)3697static int do_setattr(u64 attr, void *value, size_t size)
3668{3698{
3669 struct task_smack *tsp = smack_cred(current_cred());3699 struct task_smack *tsp = smack_cred(current_cred());
3670 struct cred *new;3700 struct cred *new;
@@ -3678,8 +3708,8 @@ static int smack_setprocattr(const char *name, void *value, size_t size) · 7 unmodified lines
3678 if (value == NULL || size == 0 || size >= SMK_LONGLABEL)3708 if (value == NULL || size == 0 || size >= SMK_LONGLABEL)
3679 return -EINVAL;3709 return -EINVAL;
3680 3710
3681 if (strcmp(name, "current") != 0)3711 if (attr != LSM_ATTR_CURRENT)
3682 return -EINVAL;3712 return -EOPNOTSUPP;
3683 3713
3684 skp = smk_import_entry(value, size);3714 skp = smk_import_entry(value, size);
3685 if (IS_ERR(skp))3715 if (IS_ERR(skp))
@@ -3718,6 +3748,49 @@ static int smack_setprocattr(const char *name, void *value, size_t size) · 32 unmodified lines
3718 return size;3748 return size;
3719}3749}
3720 3750
3751/**
3752 * smack_setselfattr - Set a Smack process attribute
3753 * @attr: which attribute to set
3754 * @ctx: buffer containing the data
3755 * @size: size of @ctx
3756 * @flags: unused
3757 *
3758 * Fill the passed user space @ctx with the details of the requested
3759 * attribute.
3760 *
3761 * Returns 0 on success, an error code otherwise.
3762 */
3763static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
3764 size_t size, u32 flags)
3765{
3766 int rc;
3767
3768 rc = do_setattr(attr, ctx->ctx, ctx->ctx_len);
3769 if (rc > 0)
3770 return 0;
3771 return rc;
3772}
3773
3774/**
3775 * smack_setprocattr - Smack process attribute setting
3776 * @name: the name of the attribute in /proc/.../attr
3777 * @value: the value to set
3778 * @size: the size of the value
3779 *
3780 * Sets the Smack value of the task. Only setting self
3781 * is permitted and only with privilege
3782 *
3783 * Returns the length of the smack label or an error code
3784 */
3785static int smack_setprocattr(const char *name, void *value, size_t size)
3786{
3787 int attr = lsm_name_to_attr(name);
3788
3789 if (attr != LSM_ATTR_UNDEF)
3790 return do_setattr(attr, value, size);
3791 return -EINVAL;
3792}
3793
3721/**3794/**
3722 * smack_unix_stream_connect - Smack access on UDS3795 * smack_unix_stream_connect - Smack access on UDS
3723 * @sock: one sock3796 * @sock: one sock
@@ -4933,6 +5006,11 @@ struct lsm_blob_sizes smack_blob_sizes __ro_after_init = { · 1209 unmodified lines
4933 .lbs_xattr_count = SMACK_INODE_INIT_XATTRS,5006 .lbs_xattr_count = SMACK_INODE_INIT_XATTRS,
4934};5007};
4935 5008
5009static const struct lsm_id smack_lsmid = {
5010 .name = "smack",
5011 .id = LSM_ID_SMACK,
5012};
5013
4936static struct security_hook_list smack_hooks[] __ro_after_init = {5014static struct security_hook_list smack_hooks[] __ro_after_init = {
4937 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),5015 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
4938 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),5016 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
@@ -4973,6 +5051,7 @@ static struct security_hook_list smack_hooks[] __ro_after_init = { · 34 unmodified lines
4973 5051
4974 LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security),5052 LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security),
4975 LSM_HOOK_INIT(file_ioctl, smack_file_ioctl),5053 LSM_HOOK_INIT(file_ioctl, smack_file_ioctl),
5054 LSM_HOOK_INIT(file_ioctl_compat, smack_file_ioctl),
4976 LSM_HOOK_INIT(file_lock, smack_file_lock),5055 LSM_HOOK_INIT(file_lock, smack_file_lock),
4977 LSM_HOOK_INIT(file_fcntl, smack_file_fcntl),5056 LSM_HOOK_INIT(file_fcntl, smack_file_fcntl),
4978 LSM_HOOK_INIT(mmap_file, smack_mmap_file),5057 LSM_HOOK_INIT(mmap_file, smack_mmap_file),
@@ -5027,6 +5106,8 @@ static struct security_hook_list smack_hooks[] __ro_after_init = { · 48 unmodified lines
5027 5106
5028 LSM_HOOK_INIT(d_instantiate, smack_d_instantiate),5107 LSM_HOOK_INIT(d_instantiate, smack_d_instantiate),
5029 5108
5109 LSM_HOOK_INIT(getselfattr, smack_getselfattr),
5110 LSM_HOOK_INIT(setselfattr, smack_setselfattr),
5030 LSM_HOOK_INIT(getprocattr, smack_getprocattr),5111 LSM_HOOK_INIT(getprocattr, smack_getprocattr),
5031 LSM_HOOK_INIT(setprocattr, smack_setprocattr),5112 LSM_HOOK_INIT(setprocattr, smack_setprocattr),
5032 5113
@@ -5140,7 +5221,7 @@ static __init int smack_init(void) · 107 unmodified lines
5140 /*5221 /*
5141 * Register with LSM5222 * Register with LSM
5142 */5223 */
5143 security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");5224 security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), &smack_lsmid);
5144 smack_enabled = 1;5225 smack_enabled = 1;
5145 5226
5146 pr_info("Smack: Initializing.\n");5227 pr_info("Smack: Initializing.\n");
security/tomoyo/tomoyo.c+9−1
@@ -6,6 +6,7 @@ · 5 unmodified lines
6 */6 */
7 7
8#include <linux/lsm_hooks.h>8#include <linux/lsm_hooks.h>
9#include <uapi/linux/lsm.h>
9#include "common.h"10#include "common.h"
10 11
11/**12/**
@@ -542,6 +543,11 @@ static void tomoyo_task_free(struct task_struct *task) · 530 unmodified lines
542 }543 }
543}544}
544 545
546static const struct lsm_id tomoyo_lsmid = {
547 .name = "tomoyo",
548 .id = LSM_ID_TOMOYO,
549};
550
545/*551/*
546 * tomoyo_security_ops is a "struct security_operations" which is used for552 * tomoyo_security_ops is a "struct security_operations" which is used for
547 * registering TOMOYO.553 * registering TOMOYO.
@@ -568,6 +574,7 @@ static struct security_hook_list tomoyo_hooks[] __ro_after_init = { · 20 unmodified lines
568 LSM_HOOK_INIT(path_rename, tomoyo_path_rename),574 LSM_HOOK_INIT(path_rename, tomoyo_path_rename),
569 LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr),575 LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr),
570 LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl),576 LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl),
577 LSM_HOOK_INIT(file_ioctl_compat, tomoyo_file_ioctl),
571 LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod),578 LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod),
572 LSM_HOOK_INIT(path_chown, tomoyo_path_chown),579 LSM_HOOK_INIT(path_chown, tomoyo_path_chown),
573 LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot),580 LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot),
@@ -595,7 +602,8 @@ static int __init tomoyo_init(void) · 21 unmodified lines
595 struct tomoyo_task *s = tomoyo_task(current);602 struct tomoyo_task *s = tomoyo_task(current);
596 603
597 /* register ourselves with the security framework */604 /* register ourselves with the security framework */
598 security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo");605 security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks),
606 &tomoyo_lsmid);
599 pr_info("TOMOYO Linux initialized\n");607 pr_info("TOMOYO Linux initialized\n");
600 s->domain_info = &tomoyo_kernel_domain;608 s->domain_info = &tomoyo_kernel_domain;
601 atomic_inc(&tomoyo_kernel_domain.users);609 atomic_inc(&tomoyo_kernel_domain.users);
security/yama/yama_lsm.c+7−1
@@ -18,6 +18,7 @@ · 17 unmodified lines
18#include <linux/task_work.h>18#include <linux/task_work.h>
19#include <linux/sched.h>19#include <linux/sched.h>
20#include <linux/spinlock.h>20#include <linux/spinlock.h>
21#include <uapi/linux/lsm.h>
21 22
22#define YAMA_SCOPE_DISABLED 023#define YAMA_SCOPE_DISABLED 0
23#define YAMA_SCOPE_RELATIONAL 124#define YAMA_SCOPE_RELATIONAL 1
@@ -421,6 +422,11 @@ static int yama_ptrace_traceme(struct task_struct *parent) · 397 unmodified lines
421 return rc;422 return rc;
422}423}
423 424
425static const struct lsm_id yama_lsmid = {
426 .name = "yama",
427 .id = LSM_ID_YAMA,
428};
429
424static struct security_hook_list yama_hooks[] __ro_after_init = {430static struct security_hook_list yama_hooks[] __ro_after_init = {
425 LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check),431 LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check),
426 LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme),432 LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme),
@@ -471,7 +477,7 @@ static inline void yama_init_sysctl(void) { } · 44 unmodified lines
471static int __init yama_init(void)477static int __init yama_init(void)
472{478{
473 pr_info("Yama: becoming mindful.\n");479 pr_info("Yama: becoming mindful.\n");
474 security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama");480 security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), &yama_lsmid);
475 yama_init_sysctl();481 yama_init_sysctl();
476 return 0;482 return 0;
477}483}
tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl+5−0
@@ -371,3 +371,8 @@ · 370 unmodified lines
371454 n64 futex_wake sys_futex_wake371454 n64 futex_wake sys_futex_wake
372455 n64 futex_wait sys_futex_wait372455 n64 futex_wait sys_futex_wait
373456 n64 futex_requeue sys_futex_requeue373456 n64 futex_requeue sys_futex_requeue
374457 n64 statmount sys_statmount
375458 n64 listmount sys_listmount
376459 n64 lsm_get_self_attr sys_lsm_get_self_attr
377460 n64 lsm_set_self_attr sys_lsm_set_self_attr
378461 n64 lsm_list_modules sys_lsm_list_modules
tools/perf/arch/powerpc/entry/syscalls/syscall.tbl+5−0
@@ -543,3 +543,8 @@ · 542 unmodified lines
543454 common futex_wake sys_futex_wake543454 common futex_wake sys_futex_wake
544455 common futex_wait sys_futex_wait544455 common futex_wait sys_futex_wait
545456 common futex_requeue sys_futex_requeue545456 common futex_requeue sys_futex_requeue
546457 common statmount sys_statmount
547458 common listmount sys_listmount
548459 common lsm_get_self_attr sys_lsm_get_self_attr
549460 common lsm_set_self_attr sys_lsm_set_self_attr
550461 common lsm_list_modules sys_lsm_list_modules
tools/perf/arch/s390/entry/syscalls/syscall.tbl+5−0
@@ -459,3 +459,8 @@ · 458 unmodified lines
459454 common futex_wake sys_futex_wake sys_futex_wake459454 common futex_wake sys_futex_wake sys_futex_wake
460455 common futex_wait sys_futex_wait sys_futex_wait460455 common futex_wait sys_futex_wait sys_futex_wait
461456 common futex_requeue sys_futex_requeue sys_futex_requeue461456 common futex_requeue sys_futex_requeue sys_futex_requeue
462457 common statmount sys_statmount sys_statmount
463458 common listmount sys_listmount sys_listmount
464459 common lsm_get_self_attr sys_lsm_get_self_attr sys_lsm_get_self_attr
465460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr
466461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl+5−0
@@ -378,6 +378,11 @@ · 377 unmodified lines
378454 common futex_wake sys_futex_wake378454 common futex_wake sys_futex_wake
379455 common futex_wait sys_futex_wait379455 common futex_wait sys_futex_wait
380456 common futex_requeue sys_futex_requeue380456 common futex_requeue sys_futex_requeue
381457 common statmount sys_statmount
382458 common listmount sys_listmount
383459 common lsm_get_self_attr sys_lsm_get_self_attr
384460 common lsm_set_self_attr sys_lsm_set_self_attr
385461 common lsm_list_modules sys_lsm_list_modules
381 386
382#387#
383# Due to a historical design error, certain syscalls are numbered differently388# Due to a historical design error, certain syscalls are numbered differently
tools/testing/selftests/Makefile+1−0
@@ -45,6 +45,7 @@ TARGETS += landlock · 44 unmodified lines
45TARGETS += lib45TARGETS += lib
46TARGETS += livepatch46TARGETS += livepatch
47TARGETS += lkdtm47TARGETS += lkdtm
48TARGETS += lsm
48TARGETS += membarrier49TARGETS += membarrier
49TARGETS += memfd50TARGETS += memfd
50TARGETS += memory-hotplug51TARGETS += memory-hotplug
tools/testing/selftests/lsm/.gitignore+1−0
@@ -0,0 +1 @@
1/*_test
tools/testing/selftests/lsm/Makefile+17−0
@@ -0,0 +1,17 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# First run: make -C ../../../.. headers_install
4
5CFLAGS += -Wall -O2 $(KHDR_INCLUDES)
6LOCAL_HDRS += common.h
7
8TEST_GEN_PROGS := lsm_get_self_attr_test lsm_list_modules_test \
9 lsm_set_self_attr_test
10
11include ../lib.mk
12
13$(OUTPUT)/lsm_get_self_attr_test: lsm_get_self_attr_test.c common.c
14$(OUTPUT)/lsm_set_self_attr_test: lsm_set_self_attr_test.c common.c
15$(OUTPUT)/lsm_list_modules_test: lsm_list_modules_test.c common.c
16
17EXTRA_CLEAN = $(OUTPUT)/common.o
tools/testing/selftests/lsm/common.c+89−0
@@ -0,0 +1,89 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Linux Security Module infrastructure tests
4 *
5 * Copyright © 2023 Casey Schaufler <casey@schaufler-ca.com>
6 */
7
8#define _GNU_SOURCE
9#include <linux/lsm.h>
10#include <fcntl.h>
11#include <string.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <sys/types.h>
16#include "common.h"
17
18#define PROCATTR "/proc/self/attr/"
19
20int read_proc_attr(const char *attr, char *value, size_t size)
21{
22 int fd;
23 int len;
24 char *path;
25
26 len = strlen(PROCATTR) + strlen(attr) + 1;
27 path = calloc(len, 1);
28 if (path == NULL)
29 return -1;
30 sprintf(path, "%s%s", PROCATTR, attr);
31
32 fd = open(path, O_RDONLY);
33 free(path);
34
35 if (fd < 0)
36 return -1;
37 len = read(fd, value, size);
38
39 close(fd);
40
41 /* Ensure value is terminated */
42 if (len <= 0 || len == size)
43 return -1;
44 value[len] = '\0';
45
46 path = strchr(value, '\n');
47 if (path)
48 *path = '\0';
49
50 return 0;
51}
52
53int read_sysfs_lsms(char *lsms, size_t size)
54{
55 FILE *fp;
56 size_t red;
57
58 fp = fopen("/sys/kernel/security/lsm", "r");
59 if (fp == NULL)
60 return -1;
61 red = fread(lsms, 1, size, fp);
62 fclose(fp);
63
64 if (red <= 0 || red == size)
65 return -1;
66 lsms[red] = '\0';
67 return 0;
68}
69
70int attr_lsm_count(void)
71{
72 char *names = calloc(sysconf(_SC_PAGESIZE), 1);
73 int count = 0;
74
75 if (!names)
76 return 0;
77
78 if (read_sysfs_lsms(names, sysconf(_SC_PAGESIZE)))
79 return 0;
80
81 if (strstr(names, "selinux"))
82 count++;
83 if (strstr(names, "smack"))
84 count++;
85 if (strstr(names, "apparmor"))
86 count++;
87
88 return count;
89}
tools/testing/selftests/lsm/common.h+33−0
@@ -0,0 +1,33 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Linux Security Module infrastructure tests
4 *
5 * Copyright © 2023 Casey Schaufler <casey@schaufler-ca.com>
6 */
7
8#ifndef lsm_get_self_attr
9static inline int lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx,
10 size_t *size, __u32 flags)
11{
12 return syscall(__NR_lsm_get_self_attr, attr, ctx, size, flags);
13}
14#endif
15
16#ifndef lsm_set_self_attr
17static inline int lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx,
18 size_t size, __u32 flags)
19{
20 return syscall(__NR_lsm_set_self_attr, attr, ctx, size, flags);
21}
22#endif
23
24#ifndef lsm_list_modules
25static inline int lsm_list_modules(__u64 *ids, size_t *size, __u32 flags)
26{
27 return syscall(__NR_lsm_list_modules, ids, size, flags);
28}
29#endif
30
31extern int read_proc_attr(const char *attr, char *value, size_t size);
32extern int read_sysfs_lsms(char *lsms, size_t size);
33int attr_lsm_count(void);
tools/testing/selftests/lsm/config+3−0
@@ -0,0 +1,3 @@
1CONFIG_SYSFS=y
2CONFIG_SECURITY=y
3CONFIG_SECURITYFS=y
tools/testing/selftests/lsm/lsm_get_self_attr_test.c+275−0
@@ -0,0 +1,275 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Linux Security Module infrastructure tests
4 * Tests for the lsm_get_self_attr system call
5 *
6 * Copyright © 2022 Casey Schaufler <casey@schaufler-ca.com>
7 */
8
9#define _GNU_SOURCE
10#include <linux/lsm.h>
11#include <fcntl.h>
12#include <string.h>
13#include <stdio.h>
14#include <unistd.h>
15#include <sys/types.h>
16#include "../kselftest_harness.h"
17#include "common.h"
18
19static struct lsm_ctx *next_ctx(struct lsm_ctx *ctxp)
20{
21 void *vp;
22
23 vp = (void *)ctxp + sizeof(*ctxp) + ctxp->ctx_len;
24 return (struct lsm_ctx *)vp;
25}
26
27TEST(size_null_lsm_get_self_attr)
28{
29 const long page_size = sysconf(_SC_PAGESIZE);
30 struct lsm_ctx *ctx = calloc(page_size, 1);
31
32 ASSERT_NE(NULL, ctx);
33 errno = 0;
34 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, NULL, 0));
35 ASSERT_EQ(EINVAL, errno);
36
37 free(ctx);
38}
39
40TEST(ctx_null_lsm_get_self_attr)
41{
42 const long page_size = sysconf(_SC_PAGESIZE);
43 size_t size = page_size;
44 int rc;
45
46 rc = lsm_get_self_attr(LSM_ATTR_CURRENT, NULL, &size, 0);
47
48 if (attr_lsm_count()) {
49 ASSERT_NE(-1, rc);
50 ASSERT_NE(1, size);
51 } else {
52 ASSERT_EQ(-1, rc);
53 }
54}
55
56TEST(size_too_small_lsm_get_self_attr)
57{
58 const long page_size = sysconf(_SC_PAGESIZE);
59 struct lsm_ctx *ctx = calloc(page_size, 1);
60 size_t size = 1;
61
62 ASSERT_NE(NULL, ctx);
63 errno = 0;
64 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size, 0));
65 if (attr_lsm_count()) {
66 ASSERT_EQ(E2BIG, errno);
67 } else {
68 ASSERT_EQ(EOPNOTSUPP, errno);
69 }
70 ASSERT_NE(1, size);
71
72 free(ctx);
73}
74
75TEST(flags_zero_lsm_get_self_attr)
76{
77 const long page_size = sysconf(_SC_PAGESIZE);
78 struct lsm_ctx *ctx = calloc(page_size, 1);
79 __u64 *syscall_lsms = calloc(page_size, 1);
80 size_t size;
81 int lsmcount;
82 int i;
83
84 ASSERT_NE(NULL, ctx);
85 errno = 0;
86 size = page_size;
87 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size,
88 LSM_FLAG_SINGLE));
89 ASSERT_EQ(EINVAL, errno);
90 ASSERT_EQ(page_size, size);
91
92 lsmcount = syscall(__NR_lsm_list_modules, syscall_lsms, &size, 0);
93 ASSERT_LE(1, lsmcount);
94 ASSERT_NE(NULL, syscall_lsms);
95
96 for (i = 0; i < lsmcount; i++) {
97 errno = 0;
98 size = page_size;
99 ctx->id = syscall_lsms[i];
100
101 if (syscall_lsms[i] == LSM_ID_SELINUX ||
102 syscall_lsms[i] == LSM_ID_SMACK ||
103 syscall_lsms[i] == LSM_ID_APPARMOR) {
104 ASSERT_EQ(1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx,
105 &size, LSM_FLAG_SINGLE));
106 } else {
107 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx,
108 &size,
109 LSM_FLAG_SINGLE));
110 }
111 }
112
113 free(ctx);
114}
115
116TEST(flags_overset_lsm_get_self_attr)
117{
118 const long page_size = sysconf(_SC_PAGESIZE);
119 struct lsm_ctx *ctx = calloc(page_size, 1);
120 size_t size;
121
122 ASSERT_NE(NULL, ctx);
123
124 errno = 0;
125 size = page_size;
126 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT | LSM_ATTR_PREV, ctx,
127 &size, 0));
128 ASSERT_EQ(EOPNOTSUPP, errno);
129
130 errno = 0;
131 size = page_size;
132 ASSERT_EQ(-1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size,
133 LSM_FLAG_SINGLE |
134 (LSM_FLAG_SINGLE << 1)));
135 ASSERT_EQ(EINVAL, errno);
136
137 free(ctx);
138}
139
140TEST(basic_lsm_get_self_attr)
141{
142 const long page_size = sysconf(_SC_PAGESIZE);
143 size_t size = page_size;
144 struct lsm_ctx *ctx = calloc(page_size, 1);
145 struct lsm_ctx *tctx = NULL;
146 __u64 *syscall_lsms = calloc(page_size, 1);
147 char *attr = calloc(page_size, 1);
148 int cnt_current = 0;
149 int cnt_exec = 0;
150 int cnt_fscreate = 0;
151 int cnt_keycreate = 0;
152 int cnt_prev = 0;
153 int cnt_sockcreate = 0;
154 int lsmcount;
155 int count;
156 int i;
157
158 ASSERT_NE(NULL, ctx);
159 ASSERT_NE(NULL, syscall_lsms);
160
161 lsmcount = syscall(__NR_lsm_list_modules, syscall_lsms, &size, 0);
162 ASSERT_LE(1, lsmcount);
163
164 for (i = 0; i < lsmcount; i++) {
165 switch (syscall_lsms[i]) {
166 case LSM_ID_SELINUX:
167 cnt_current++;
168 cnt_exec++;
169 cnt_fscreate++;
170 cnt_keycreate++;
171 cnt_prev++;
172 cnt_sockcreate++;
173 break;
174 case LSM_ID_SMACK:
175 cnt_current++;
176 break;
177 case LSM_ID_APPARMOR:
178 cnt_current++;
179 cnt_exec++;
180 cnt_prev++;
181 break;
182 default:
183 break;
184 }
185 }
186
187 if (cnt_current) {
188 size = page_size;
189 count = lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size, 0);
190 ASSERT_EQ(cnt_current, count);
191 tctx = ctx;
192 ASSERT_EQ(0, read_proc_attr("current", attr, page_size));
193 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
194 for (i = 1; i < count; i++) {
195 tctx = next_ctx(tctx);
196 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
197 }
198 }
199 if (cnt_exec) {
200 size = page_size;
201 count = lsm_get_self_attr(LSM_ATTR_EXEC, ctx, &size, 0);
202 ASSERT_GE(cnt_exec, count);
203 if (count > 0) {
204 tctx = ctx;
205 if (read_proc_attr("exec", attr, page_size) == 0)
206 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
207 }
208 for (i = 1; i < count; i++) {
209 tctx = next_ctx(tctx);
210 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
211 }
212 }
213 if (cnt_fscreate) {
214 size = page_size;
215 count = lsm_get_self_attr(LSM_ATTR_FSCREATE, ctx, &size, 0);
216 ASSERT_GE(cnt_fscreate, count);
217 if (count > 0) {
218 tctx = ctx;
219 if (read_proc_attr("fscreate", attr, page_size) == 0)
220 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
221 }
222 for (i = 1; i < count; i++) {
223 tctx = next_ctx(tctx);
224 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
225 }
226 }
227 if (cnt_keycreate) {
228 size = page_size;
229 count = lsm_get_self_attr(LSM_ATTR_KEYCREATE, ctx, &size, 0);
230 ASSERT_GE(cnt_keycreate, count);
231 if (count > 0) {
232 tctx = ctx;
233 if (read_proc_attr("keycreate", attr, page_size) == 0)
234 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
235 }
236 for (i = 1; i < count; i++) {
237 tctx = next_ctx(tctx);
238 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
239 }
240 }
241 if (cnt_prev) {
242 size = page_size;
243 count = lsm_get_self_attr(LSM_ATTR_PREV, ctx, &size, 0);
244 ASSERT_GE(cnt_prev, count);
245 if (count > 0) {
246 tctx = ctx;
247 ASSERT_EQ(0, read_proc_attr("prev", attr, page_size));
248 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
249 for (i = 1; i < count; i++) {
250 tctx = next_ctx(tctx);
251 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
252 }
253 }
254 }
255 if (cnt_sockcreate) {
256 size = page_size;
257 count = lsm_get_self_attr(LSM_ATTR_SOCKCREATE, ctx, &size, 0);
258 ASSERT_GE(cnt_sockcreate, count);
259 if (count > 0) {
260 tctx = ctx;
261 if (read_proc_attr("sockcreate", attr, page_size) == 0)
262 ASSERT_EQ(0, strcmp((char *)tctx->ctx, attr));
263 }
264 for (i = 1; i < count; i++) {
265 tctx = next_ctx(tctx);
266 ASSERT_NE(0, strcmp((char *)tctx->ctx, attr));
267 }
268 }
269
270 free(ctx);
271 free(attr);
272 free(syscall_lsms);
273}
274
275TEST_HARNESS_MAIN
tools/testing/selftests/lsm/lsm_list_modules_test.c+137−0
@@ -0,0 +1,137 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Linux Security Module infrastructure tests
4 * Tests for the lsm_list_modules system call
5 *
6 * Copyright © 2022 Casey Schaufler <casey@schaufler-ca.com>
7 */
8
9#define _GNU_SOURCE
10#include <linux/lsm.h>
11#include <string.h>
12#include <stdio.h>
13#include <unistd.h>
14#include <sys/types.h>
15#include "../kselftest_harness.h"
16#include "common.h"
17
18TEST(size_null_lsm_list_modules)
19{
20 const long page_size = sysconf(_SC_PAGESIZE);
21 __u64 *syscall_lsms = calloc(page_size, 1);
22
23 ASSERT_NE(NULL, syscall_lsms);
24 errno = 0;
25 ASSERT_EQ(-1, lsm_list_modules(syscall_lsms, NULL, 0));
26 ASSERT_EQ(EFAULT, errno);
27
28 free(syscall_lsms);
29}
30
31TEST(ids_null_lsm_list_modules)
32{
33 const long page_size = sysconf(_SC_PAGESIZE);
34 size_t size = page_size;
35
36 errno = 0;
37 ASSERT_EQ(-1, lsm_list_modules(NULL, &size, 0));
38 ASSERT_EQ(EFAULT, errno);
39 ASSERT_NE(1, size);
40}
41
42TEST(size_too_small_lsm_list_modules)
43{
44 const long page_size = sysconf(_SC_PAGESIZE);
45 __u64 *syscall_lsms = calloc(page_size, 1);
46 size_t size = 1;
47
48 ASSERT_NE(NULL, syscall_lsms);
49 errno = 0;
50 ASSERT_EQ(-1, lsm_list_modules(syscall_lsms, &size, 0));
51 ASSERT_EQ(E2BIG, errno);
52 ASSERT_NE(1, size);
53
54 free(syscall_lsms);
55}
56
57TEST(flags_set_lsm_list_modules)
58{
59 const long page_size = sysconf(_SC_PAGESIZE);
60 __u64 *syscall_lsms = calloc(page_size, 1);
61 size_t size = page_size;
62
63 ASSERT_NE(NULL, syscall_lsms);
64 errno = 0;
65 ASSERT_EQ(-1, lsm_list_modules(syscall_lsms, &size, 7));
66 ASSERT_EQ(EINVAL, errno);
67 ASSERT_EQ(page_size, size);
68
69 free(syscall_lsms);
70}
71
72TEST(correct_lsm_list_modules)
73{
74 const long page_size = sysconf(_SC_PAGESIZE);
75 size_t size = page_size;
76 __u64 *syscall_lsms = calloc(page_size, 1);
77 char *sysfs_lsms = calloc(page_size, 1);
78 char *name;
79 char *cp;
80 int count;
81 int i;
82
83 ASSERT_NE(NULL, sysfs_lsms);
84 ASSERT_NE(NULL, syscall_lsms);
85 ASSERT_EQ(0, read_sysfs_lsms(sysfs_lsms, page_size));
86
87 count = lsm_list_modules(syscall_lsms, &size, 0);
88 ASSERT_LE(1, count);
89 cp = sysfs_lsms;
90 for (i = 0; i < count; i++) {
91 switch (syscall_lsms[i]) {
92 case LSM_ID_CAPABILITY:
93 name = "capability";
94 break;
95 case LSM_ID_SELINUX:
96 name = "selinux";
97 break;
98 case LSM_ID_SMACK:
99 name = "smack";
100 break;
101 case LSM_ID_TOMOYO:
102 name = "tomoyo";
103 break;
104 case LSM_ID_APPARMOR:
105 name = "apparmor";
106 break;
107 case LSM_ID_YAMA:
108 name = "yama";
109 break;
110 case LSM_ID_LOADPIN:
111 name = "loadpin";
112 break;
113 case LSM_ID_SAFESETID:
114 name = "safesetid";
115 break;
116 case LSM_ID_LOCKDOWN:
117 name = "lockdown";
118 break;
119 case LSM_ID_BPF:
120 name = "bpf";
121 break;
122 case LSM_ID_LANDLOCK:
123 name = "landlock";
124 break;
125 default:
126 name = "INVALID";
127 break;
128 }
129 ASSERT_EQ(0, strncmp(cp, name, strlen(name)));
130 cp += strlen(name) + 1;
131 }
132
133 free(sysfs_lsms);
134 free(syscall_lsms);
135}
136
137TEST_HARNESS_MAIN
tools/testing/selftests/lsm/lsm_set_self_attr_test.c+74−0
@@ -0,0 +1,74 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Linux Security Module infrastructure tests
4 * Tests for the lsm_set_self_attr system call
5 *
6 * Copyright © 2022 Casey Schaufler <casey@schaufler-ca.com>
7 */
8
9#define _GNU_SOURCE
10#include <linux/lsm.h>
11#include <string.h>
12#include <stdio.h>
13#include <unistd.h>
14#include <sys/types.h>
15#include "../kselftest_harness.h"
16#include "common.h"
17
18TEST(ctx_null_lsm_set_self_attr)
19{
20 ASSERT_EQ(-1, lsm_set_self_attr(LSM_ATTR_CURRENT, NULL,
21 sizeof(struct lsm_ctx), 0));
22}
23
24TEST(size_too_small_lsm_set_self_attr)
25{
26 const long page_size = sysconf(_SC_PAGESIZE);
27 struct lsm_ctx *ctx = calloc(page_size, 1);
28 size_t size = page_size;
29
30 ASSERT_NE(NULL, ctx);
31 if (attr_lsm_count()) {
32 ASSERT_LE(1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size,
33 0));
34 }
35 ASSERT_EQ(-1, lsm_set_self_attr(LSM_ATTR_CURRENT, ctx, 1, 0));
36
37 free(ctx);
38}
39
40TEST(flags_zero_lsm_set_self_attr)
41{
42 const long page_size = sysconf(_SC_PAGESIZE);
43 struct lsm_ctx *ctx = calloc(page_size, 1);
44 size_t size = page_size;
45
46 ASSERT_NE(NULL, ctx);
47 if (attr_lsm_count()) {
48 ASSERT_LE(1, lsm_get_self_attr(LSM_ATTR_CURRENT, ctx, &size,
49 0));
50 }
51 ASSERT_EQ(-1, lsm_set_self_attr(LSM_ATTR_CURRENT, ctx, size, 1));
52
53 free(ctx);
54}
55
56TEST(flags_overset_lsm_set_self_attr)
57{
58 const long page_size = sysconf(_SC_PAGESIZE);
59 char *ctx = calloc(page_size, 1);
60 size_t size = page_size;
61 struct lsm_ctx *tctx = (struct lsm_ctx *)ctx;
62
63 ASSERT_NE(NULL, ctx);
64 if (attr_lsm_count()) {
65 ASSERT_LE(1, lsm_get_self_attr(LSM_ATTR_CURRENT, tctx, &size,
66 0));
67 }
68 ASSERT_EQ(-1, lsm_set_self_attr(LSM_ATTR_CURRENT | LSM_ATTR_PREV, tctx,
69 size, 0));
70
71 free(ctx);
72}
73
74TEST_HARNESS_MAIN