summaryrefslogtreecommitdiff
path: root/security/selinux/ss/services.c
AgeCommit message (Collapse)Author
2024-11-18Merge tag 'lsm-pr-20241112' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm Pull lsm updates from Paul Moore: "Thirteen patches, all focused on moving away from the current 'secid' LSM identifier to a richer 'lsm_prop' structure. This move will help reduce the translation that is necessary in many LSMs, offering better performance, and make it easier to support different LSMs in the future" * tag 'lsm-pr-20241112' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm: lsm: remove lsm_prop scaffolding netlabel,smack: use lsm_prop for audit data audit: change context data from secid to lsm_prop lsm: create new security_cred_getlsmprop LSM hook audit: use an lsm_prop in audit_names lsm: use lsm_prop in security_inode_getsecid lsm: use lsm_prop in security_current_getsecid audit: update shutdown LSM data lsm: use lsm_prop in security_ipc_getsecid audit: maintain an lsm_prop in audit_context lsm: add lsmprop_to_secctx hook lsm: use lsm_prop in security_audit_rule_match lsm: add the lsm_prop data structure
2024-10-11lsm: remove lsm_prop scaffoldingCasey Schaufler
Remove the scaffold member from the lsm_prop. Remove the remaining places it is being set. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> [PM: subj line tweak] Signed-off-by: Paul Moore <paul@paul-moore.com>
2024-10-11lsm: use lsm_prop in security_audit_rule_matchCasey Schaufler
Change the secid parameter of security_audit_rule_match to a lsm_prop structure pointer. Pass the entry from the lsm_prop structure for the approprite slot to the LSM hook. Change the users of security_audit_rule_match to use the lsm_prop instead of a u32. The scaffolding function lsmprop_init() fills the structure with the value of the old secid, ensuring that it is available to the appropriate module hook. The sources of the secid, security_task_getsecid() and security_inode_getsecid(), will be converted to use the lsm_prop structure later in the series. At that point the use of lsmprop_init() is dropped. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> [PM: subject line tweak] Signed-off-by: Paul Moore <paul@paul-moore.com>
2024-10-07selinux: Add netlink xperm supportThiébaud Weksteen
Reuse the existing extended permissions infrastructure to support policies based on the netlink message types. A new policy capability "netlink_xperm" is introduced. When disabled, the previous behaviour is preserved. That is, netlink_send will rely on the permission mappings defined in nlmsgtab.c (e.g, nlmsg_read for RTM_GETADDR on NETLINK_ROUTE). When enabled, the mappings are ignored and the generic "nlmsg" permission is used instead. The new "nlmsg" permission is an extended permission. The 16 bits of the extended permission are mapped to the nlmsg_type field. Example policy on Android, preventing regular apps from accessing the device's MAC address and ARP table, but allowing this access to privileged apps, looks as follows: allow netdomain self:netlink_route_socket { create read getattr write setattr lock append connect getopt setopt shutdown nlmsg }; allowxperm netdomain self:netlink_route_socket nlmsg ~{ RTM_GETLINK RTM_GETNEIGH RTM_GETNEIGHTBL }; allowxperm priv_app self:netlink_route_socket nlmsg { RTM_GETLINK RTM_GETNEIGH RTM_GETNEIGHTBL }; The constants in the example above (e.g., RTM_GETLINK) are explicitly defined in the policy. It is possible to generate policies to support kernels that may or may not have the capability enabled by generating a rule for each scenario. For instance: allow domain self:netlink_audit_socket nlmsg_read; allow domain self:netlink_audit_socket nlmsg; allowxperm domain self:netlink_audit_socket nlmsg { AUDIT_GET }; The approach of defining a new permission ("nlmsg") instead of relying on the existing permissions (e.g., "nlmsg_read", "nlmsg_readpriv" or "nlmsg_tty_audit") has been preferred because: 1. This is similar to the other extended permission ("ioctl"); 2. With the new extended permission, the coarse-grained mapping is not necessary anymore. It could eventually be removed, which would be impossible if the extended permission was defined below these. 3. Having a single extra extended permission considerably simplifies the implementation here and in libselinux. Signed-off-by: Thiébaud Weksteen <tweek@google.com> Signed-off-by: Bram Bonné <brambonne@google.com> [PM: manual merge fixes for sock_skip_has_perm()] Signed-off-by: Paul Moore <paul@paul-moore.com>
2024-07-29selinux: Streamline type determination in security_compute_sidCanfeng Guo
Simplifies the logic for determining the security context type in security_compute_sid, enhancing readability and efficiency. Consolidates default type assignment logic next to type transition checks, removing redundancy and improving code flow. Signed-off-by: Canfeng Guo <guocanfeng@uniontech.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2024-06-13ima: Avoid blocking in RCU read-side critical sectionGUO Zihua
A panic happens in ima_match_policy: BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 PGD 42f873067 P4D 0 Oops: 0000 [#1] SMP NOPTI CPU: 5 PID: 1286325 Comm: kubeletmonit.sh Kdump: loaded Tainted: P Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015 RIP: 0010:ima_match_policy+0x84/0x450 Code: 49 89 fc 41 89 cf 31 ed 89 44 24 14 eb 1c 44 39 7b 18 74 26 41 83 ff 05 74 20 48 8b 1b 48 3b 1d f2 b9 f4 00 0f 84 9c 01 00 00 <44> 85 73 10 74 ea 44 8b 6b 14 41 f6 c5 01 75 d4 41 f6 c5 02 74 0f RSP: 0018:ff71570009e07a80 EFLAGS: 00010207 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000200 RDX: ffffffffad8dc7c0 RSI: 0000000024924925 RDI: ff3e27850dea2000 RBP: 0000000000000000 R08: 0000000000000000 R09: ffffffffabfce739 R10: ff3e27810cc42400 R11: 0000000000000000 R12: ff3e2781825ef970 R13: 00000000ff3e2785 R14: 000000000000000c R15: 0000000000000001 FS: 00007f5195b51740(0000) GS:ff3e278b12d40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000010 CR3: 0000000626d24002 CR4: 0000000000361ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ima_get_action+0x22/0x30 process_measurement+0xb0/0x830 ? page_add_file_rmap+0x15/0x170 ? alloc_set_pte+0x269/0x4c0 ? prep_new_page+0x81/0x140 ? simple_xattr_get+0x75/0xa0 ? selinux_file_open+0x9d/0xf0 ima_file_check+0x64/0x90 path_openat+0x571/0x1720 do_filp_open+0x9b/0x110 ? page_counter_try_charge+0x57/0xc0 ? files_cgroup_alloc_fd+0x38/0x60 ? __alloc_fd+0xd4/0x250 ? do_sys_open+0x1bd/0x250 do_sys_open+0x1bd/0x250 do_syscall_64+0x5d/0x1d0 entry_SYSCALL_64_after_hwframe+0x65/0xca Commit c7423dbdbc9e ("ima: Handle -ESTALE returned by ima_filter_rule_match()") introduced call to ima_lsm_copy_rule within a RCU read-side critical section which contains kmalloc with GFP_KERNEL. This implies a possible sleep and violates limitations of RCU read-side critical sections on non-PREEMPT systems. Sleeping within RCU read-side critical section might cause synchronize_rcu() returning early and break RCU protection, allowing a UAF to happen. The root cause of this issue could be described as follows: | Thread A | Thread B | | |ima_match_policy | | | rcu_read_lock | |ima_lsm_update_rule | | | synchronize_rcu | | | | kmalloc(GFP_KERNEL)| | | sleep | ==> synchronize_rcu returns early | kfree(entry) | | | | entry = entry->next| ==> UAF happens and entry now becomes NULL (or could be anything). | | entry->action | ==> Accessing entry might cause panic. To fix this issue, we are converting all kmalloc that is called within RCU read-side critical section to use GFP_ATOMIC. Fixes: c7423dbdbc9e ("ima: Handle -ESTALE returned by ima_filter_rule_match()") Cc: stable@vger.kernel.org Signed-off-by: GUO Zihua <guozihua@huawei.com> Acked-by: John Johansen <john.johansen@canonical.com> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> Reviewed-by: Casey Schaufler <casey@schaufler-ca.com> [PM: fixed missing comment, long lines, !CONFIG_IMA_LSM_RULES case] Signed-off-by: Paul Moore <paul@paul-moore.com>
2024-04-30selinux: avoid printk_ratelimit()Christian Göttsche
The usage of printk_ratelimit() is discouraged, see include/linux/printk.h, thus use pr_warn_ratelimited(). While editing this line address the following checkpatch warning: WARNING: Integer promotion: Using 'h' in '%hu' is unnecessary Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-11-21selinux: introduce an initial SID for early boot processesOndrej Mosnacek
Currently, SELinux doesn't allow distinguishing between kernel threads and userspace processes that are started before the policy is first loaded - both get the label corresponding to the kernel SID. The only way a process that persists from early boot can get a meaningful label is by doing a voluntary dyntransition or re-executing itself. Reusing the kernel label for userspace processes is problematic for several reasons: 1. The kernel is considered to be a privileged domain and generally needs to have a wide range of permissions allowed to work correctly, which prevents the policy writer from effectively hardening against early boot processes that might remain running unintentionally after the policy is loaded (they represent a potential extra attack surface that should be mitigated). 2. Despite the kernel being treated as a privileged domain, the policy writer may want to impose certain special limitations on kernel threads that may conflict with the requirements of intentional early boot processes. For example, it is a good hardening practice to limit what executables the kernel can execute as usermode helpers and to confine the resulting usermode helper processes. However, a (legitimate) process surviving from early boot may need to execute a different set of executables. 3. As currently implemented, overlayfs remembers the security context of the process that created an overlayfs mount and uses it to bound subsequent operations on files using this context. If an overlayfs mount is created before the SELinux policy is loaded, these "mounter" checks are made against the kernel context, which may clash with restrictions on the kernel domain (see 2.). To resolve this, introduce a new initial SID (reusing the slot of the former "init" initial SID) that will be assigned to any userspace process started before the policy is first loaded. This is easy to do, as we can simply label any process that goes through the bprm_creds_for_exec LSM hook with the new init-SID instead of propagating the kernel SID from the parent. To provide backwards compatibility for existing policies that are unaware of this new semantic of the "init" initial SID, introduce a new policy capability "userspace_initial_context" and set the "init" SID to the same context as the "kernel" SID unless this capability is set by the policy. Another small backwards compatibility measure is needed in security_sid_to_context_core() for before the initial SELinux policy load - see the code comment for explanation. Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com> [PM: edited comments based on feedback/discussion] Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-08-09selinux: make left shifts well definedChristian Göttsche
The loops upper bound represent the number of permissions used (for the current class or in general). The limit for this is 32, thus we might left shift of one less, 31. Shifting a base of 1 results in undefined behavior; use (u32)1 as base. Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-08-09selinux: update type for number of class permissions in services codeChristian Göttsche
Security classes have only up to 32 permissions, hence using an u16 is sufficient (while improving padding in struct selinux_mapping). Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-08-03selinux: avoid implicit conversions in services codeChristian Göttsche
Use u32 as the output parameter type in security_get_classes() and security_get_permissions(), based on the type of the symtab nprim member. Declare the read-only class string parameter of security_get_permissions() const. Avoid several implicit conversions by using the identical type for the destination. Use the type identical to the source for local variables. Signed-off-by: Christian Göttsche <cgzones@googlemail.com> [PM: cleanup extra whitespace in subject] Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-07-19selinux: update my email addressStephen Smalley
Update my email address; MAINTAINERS was updated some time ago. Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-07-19selinux: drop avtab_search()Christian Göttsche
avtab_search() shares the same logic with avtab_search_node(), except that it returns, if found, a pointer to the struct avtab_node member datum instead of the node itself. Since the member is an embedded struct, and not a pointer, the returned value of avtab_search() and avtab_search_node() will always in unison either be NULL or non-NULL. Drop avtab_search() and replace its calls by avtab_search_node() to deduplicate logic and adopt the only caller caring for the type of the returned value accordingly. Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-07-18selinux: use consistent type for AV rule specifierChristian Göttsche
The specifier for avtab keys is always supplied with a type of u16, either as a macro to security_compute_sid() or the member specified of the struct avtab_key. Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-05-08selinux: small cleanups in selinux_audit_rule_init()Paul Moore
A few small tweaks to selinux_audit_rule_init(): - Adjust how we use the @rc variable so we are not doing any extra work in the common/success case. - Related to the above, rework the 'out' jump label so that the success and error paths are different, simplifying both. - Cleanup some of the vertical whitespace while we are making the other changes. Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-05-08selinux: adjust typos in commentsChristian Göttsche
Found by codespell(1) Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2023-03-14selinux: stop passing selinux_state pointers and their offspringStephen Smalley
Linus observed that the pervasive passing of selinux_state pointers introduced by me in commit aa8e712cee93 ("selinux: wrap global selinux state") adds overhead and complexity without providing any benefit. The original idea was to pave the way for SELinux namespaces but those have not yet been implemented and there isn't currently a concrete plan to do so. Remove the passing of the selinux_state pointers, reverting to direct use of the single global selinux_state, and likewise remove passing of child pointers like the selinux_avc. The selinux_policy pointer remains as it is needed for atomic switching of policies. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Reported-by: kernel test robot <lkp@intel.com> Link: https://lore.kernel.org/oe-kbuild-all/202303101057.mZ3Gv5fK-lkp@intel.com/ Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2022-12-13Merge tag 'selinux-pr-20221212' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux Pull selinux updates from Paul Moore: "Two SELinux patches: one increases the sleep time on deprecated functionality, and one removes the indirect calls in the sidtab context conversion code" * tag 'selinux-pr-20221212' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: remove the sidtab context conversion indirect calls selinux: increase the deprecation sleep for checkreqprot and runtime disable
2022-11-09selinux: remove the sidtab context conversion indirect callsPaul Moore
The sidtab conversion code has support for multiple context conversion routines through the use of function pointers and indirect calls. However, the reality is that all current users rely on the same conversion routine: convert_context(). This patch does away with this extra complexity and replaces the indirect calls with direct function calls; allowing us to remove a layer of obfuscation and create cleaner, more maintainable code. Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2022-10-19selinux: enable use of both GFP_KERNEL and GFP_ATOMIC in convert_context()GONG, Ruiqi
The following warning was triggered on a hardware environment: SELinux: Converting 162 SID table entries... BUG: sleeping function called from invalid context at __might_sleep+0x60/0x74 0x0 in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 5943, name: tar CPU: 7 PID: 5943 Comm: tar Tainted: P O 5.10.0 #1 Call trace: dump_backtrace+0x0/0x1c8 show_stack+0x18/0x28 dump_stack+0xe8/0x15c ___might_sleep+0x168/0x17c __might_sleep+0x60/0x74 __kmalloc_track_caller+0xa0/0x7dc kstrdup+0x54/0xac convert_context+0x48/0x2e4 sidtab_context_to_sid+0x1c4/0x36c security_context_to_sid_core+0x168/0x238 security_context_to_sid_default+0x14/0x24 inode_doinit_use_xattr+0x164/0x1e4 inode_doinit_with_dentry+0x1c0/0x488 selinux_d_instantiate+0x20/0x34 security_d_instantiate+0x70/0xbc d_splice_alias+0x4c/0x3c0 ext4_lookup+0x1d8/0x200 [ext4] __lookup_slow+0x12c/0x1e4 walk_component+0x100/0x200 path_lookupat+0x88/0x118 filename_lookup+0x98/0x130 user_path_at_empty+0x48/0x60 vfs_statx+0x84/0x140 vfs_fstatat+0x20/0x30 __se_sys_newfstatat+0x30/0x74 __arm64_sys_newfstatat+0x1c/0x2c el0_svc_common.constprop.0+0x100/0x184 do_el0_svc+0x1c/0x2c el0_svc+0x20/0x34 el0_sync_handler+0x80/0x17c el0_sync+0x13c/0x140 SELinux: Context system_u:object_r:pssp_rsyslog_log_t:s0:c0 is not valid (left unmapped). It was found that within a critical section of spin_lock_irqsave in sidtab_context_to_sid(), convert_context() (hooked by sidtab_convert_params.func) might cause the process to sleep via allocating memory with GFP_KERNEL, which is problematic. As Ondrej pointed out [1], convert_context()/sidtab_convert_params.func has another caller sidtab_convert_tree(), which is okay with GFP_KERNEL. Therefore, fix this problem by adding a gfp_t argument for convert_context()/sidtab_convert_params.func and pass GFP_KERNEL/_ATOMIC properly in individual callers. Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20221018120111.1474581-1-gongruiqi1@huawei.com/ [1] Reported-by: Tan Ninghao <tanninghao1@huawei.com> Fixes: ee1a84fdfeed ("selinux: overhaul sidtab to fix bug and improve performance") Signed-off-by: GONG, Ruiqi <gongruiqi1@huawei.com> Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com> [PM: wrap long BUG() output lines, tweak subject line] Signed-off-by: Paul Moore <paul@paul-moore.com>
2022-06-13selinux: fix memleak in security_read_state_kernel()Xiu Jianfeng
In this function, it directly returns the result of __security_read_policy without freeing the allocated memory in *data, cause memory leak issue, so free the memory if __security_read_policy failed. Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com> [PM: subject line tweak] Signed-off-by: Paul Moore <paul@paul-moore.com>
2022-05-03selinux: declare data arrays constChristian Göttsche
The arrays for the policy capability names, the initial sid identifiers and the class and permission names are not changed at runtime. Declare them const to avoid accidental modification. Do not override the classmap and the initial sid list in the build time script genheaders. Check flose(3) is successful in genheaders.c, otherwise the written data might be corrupted or incomplete. Signed-off-by: Christian Göttsche <cgzones@googlemail.com> [PM: manual merge due to fuzz, minor style tweaks] Signed-off-by: Paul Moore <paul@paul-moore.com>
2022-05-03selinux: fix indentation level of mls_ops blockChristian Göttsche
Add one level of indentation to the code block of the label mls_ops in constraint_expr_eval(), to adjust the trailing break; to the parent case: branch. Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2022-04-04selinux: Remove redundant assignmentsMichal Orzel
Get rid of redundant assignments which end up in values not being read either because they are overwritten or the function ends. Reported by clang-tidy [deadcode.DeadStores] Signed-off-by: Michal Orzel <michalorzel.eng@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2022-02-18selinux: drop return statement at end of void functionsChristian Göttsche
Those return statements at the end of a void function are redundant. Reported by clang-tidy [readability-redundant-control-flow] Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2022-01-26selinux: drop cast to same typeChristian Göttsche
Both the lvalue scontextp and rvalue scontext are of the type char*. Drop the redundant explicit cast not needed since commit 9a59daa03df7 ("SELinux: fix sleeping allocation in security_context_to_sid"), where the type of scontext changed from const char* to char*. Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2022-01-25selinux: declare path parameters of _genfs_sid constChristian Göttsche
The path parameter is only read from in security_genfs_sid(), selinux_policy_genfs_sid() and __security_genfs_sid(). Since a string literal is passed as argument, declare the parameter const. Also align the parameter names in the declaration and definition. Reported by clang [-Wwrite-strings]: security/selinux/hooks.c:553:60: error: passing 'const char [2]' to parameter of type 'char *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers] rc = security_genfs_sid(&selinux_state, ... , /, ^~~ ./security/selinux/include/security.h:389:36: note: passing argument to parameter 'name' here const char *fstype, char *name, u16 sclass, ^ Signed-off-by: Christian Göttsche <cgzones@googlemail.com> [PM: wrapped description] Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-10-13selinux: fix all of the W=1 build warningsPaul Moore
There were a number of places in the code where the function definition did not match the associated comment block as well at least one file where the appropriate header files were not included (missing function declaration/prototype); this patch fixes all of these issue such that building the SELinux code with "W=1" is now warning free. % make W=1 security/selinux/ Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-10-11selinux: fix race condition when computing ocontext SIDsOndrej Mosnacek
Current code contains a lot of racy patterns when converting an ocontext's context structure to an SID. This is being done in a "lazy" fashion, such that the SID is looked up in the SID table only when it's first needed and then cached in the "sid" field of the ocontext structure. However, this is done without any locking or memory barriers and is thus unsafe. Between commits 24ed7fdae669 ("selinux: use separate table for initial SID lookup") and 66f8e2f03c02 ("selinux: sidtab reverse lookup hash table"), this race condition lead to an actual observable bug, because a pointer to the shared sid field was passed directly to sidtab_context_to_sid(), which was using this location to also store an intermediate value, which could have been read by other threads and interpreted as an SID. In practice this caused e.g. new mounts to get a wrong (seemingly random) filesystem context, leading to strange denials. This bug has been spotted in the wild at least twice, see [1] and [2]. Fix the race condition by making all the racy functions use a common helper that ensures the ocontext::sid accesses are made safely using the appropriate SMP constructs. Note that security_netif_sid() was populating the sid field of both contexts stored in the ocontext, but only the first one was actually used. The SELinux wiki's documentation on the "netifcon" policy statement [3] suggests that using only the first context is intentional. I kept only the handling of the first context here, as there is really no point in doing the SID lookup for the unused one. I wasn't able to reproduce the bug mentioned above on any kernel that includes commit 66f8e2f03c02, even though it has been reported that the issue occurs with that commit, too, just less frequently. Thus, I wasn't able to verify that this patch fixes the issue, but it makes sense to avoid the race condition regardless. [1] https://github.com/containers/container-selinux/issues/89 [2] https://lists.fedoraproject.org/archives/list/selinux@lists.fedoraproject.org/thread/6DMTAMHIOAOEMUAVTULJD45JZU7IBAFM/ [3] https://selinuxproject.org/page/NetworkStatements#netifcon Cc: stable@vger.kernel.org Cc: Xinjie Zheng <xinjie@google.com> Reported-by: Sujithra Periasamy <sujithra@google.com> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-07-14selinux: return early for possible NULL audit buffersAustin Kim
audit_log_start() may return NULL in below cases: - when audit is not initialized. - when audit backlog limit exceeds. After the call to audit_log_start() is made and then possible NULL audit buffer argument is passed to audit_log_*() functions, audit_log_*() functions return immediately in case of a NULL audit buffer argument. But it is optimal to return early when audit_log_start() returns NULL, because it is not necessary for audit_log_*() functions to be called with NULL audit buffer argument. So add exception handling for possible NULL audit buffers where return value can be handled from callers. Signed-off-by: Austin Kim <austin.kim@lge.com> [PM: tweak subject line] Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-06-11selinux: Fix kernel-docYang Li
Fix function name and add comment for parameter state in ss/services.c kernel-doc to remove some warnings found by running make W=1 LLVM=1. Reported-by: Abaci Robot <abaci@linux.alibaba.com> Signed-off-by: Yang Li <yang.lee@linux.alibaba.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-05-10selinux: Remove redundant assignment to rcJiapeng Chong
Variable rc is set to '-EINVAL' but this value is never read as it is overwritten or not used later on, hence it is a redundant assignment and can be removed. Cleans up the following clang-analyzer warning: security/selinux/ss/services.c:2103:3: warning: Value stored to 'rc' is never read [clang-analyzer-deadcode.DeadStores]. security/selinux/ss/services.c:2079:2: warning: Value stored to 'rc' is never read [clang-analyzer-deadcode.DeadStores]. security/selinux/ss/services.c:2071:2: warning: Value stored to 'rc' is never read [clang-analyzer-deadcode.DeadStores]. security/selinux/ss/services.c:2062:2: warning: Value stored to 'rc' is never read [clang-analyzer-deadcode.DeadStores]. security/selinux/ss/policydb.c:2592:3: warning: Value stored to 'rc' is never read [clang-analyzer-deadcode.DeadStores]. Reported-by: Abaci Robot <abaci@linux.alibaba.com> Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-05-01Merge tag 'landlock_v34' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security Pull Landlock LSM from James Morris: "Add Landlock, a new LSM from Mickaël Salaün. Briefly, Landlock provides for unprivileged application sandboxing. From Mickaël's cover letter: "The goal of Landlock is to enable to restrict ambient rights (e.g. global filesystem access) for a set of processes. Because Landlock is a stackable LSM [1], it makes possible to create safe security sandboxes as new security layers in addition to the existing system-wide access-controls. This kind of sandbox is expected to help mitigate the security impact of bugs or unexpected/malicious behaviors in user-space applications. Landlock empowers any process, including unprivileged ones, to securely restrict themselves. Landlock is inspired by seccomp-bpf but instead of filtering syscalls and their raw arguments, a Landlock rule can restrict the use of kernel objects like file hierarchies, according to the kernel semantic. Landlock also takes inspiration from other OS sandbox mechanisms: XNU Sandbox, FreeBSD Capsicum or OpenBSD Pledge/Unveil. In this current form, Landlock misses some access-control features. This enables to minimize this patch series and ease review. This series still addresses multiple use cases, especially with the combined use of seccomp-bpf: applications with built-in sandboxing, init systems, security sandbox tools and security-oriented APIs [2]" The cover letter and v34 posting is here: https://lore.kernel.org/linux-security-module/20210422154123.13086-1-mic@digikod.net/ See also: https://landlock.io/ This code has had extensive design discussion and review over several years" Link: https://lore.kernel.org/lkml/50db058a-7dde-441b-a7f9-f6837fe8b69f@schaufler-ca.com/ [1] Link: https://lore.kernel.org/lkml/f646e1c7-33cf-333f-070c-0a40ad0468cd@digikod.net/ [2] * tag 'landlock_v34' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: landlock: Enable user space to infer supported features landlock: Add user and kernel documentation samples/landlock: Add a sandbox manager example selftests/landlock: Add user space tests landlock: Add syscall implementations arch: Wire up Landlock syscalls fs,security: Add sb_delete hook landlock: Support filesystem access-control LSM: Infrastructure management of the superblock landlock: Add ptrace restrictions landlock: Set up the security framework and manage credentials landlock: Add ruleset and domain management landlock: Add object management
2021-04-27Merge tag 'selinux-pr-20210426' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux Pull selinux updates from Paul Moore: - Add support for measuring the SELinux state and policy capabilities using IMA. - A handful of SELinux/NFS patches to compare the SELinux state of one mount with a set of mount options. Olga goes into more detail in the patch descriptions, but this is important as it allows more flexibility when using NFS and SELinux context mounts. - Properly differentiate between the subjective and objective LSM credentials; including support for the SELinux and Smack. My clumsy attempt at a proper fix for AppArmor didn't quite pass muster so John is working on a proper AppArmor patch, in the meantime this set of patches shouldn't change the behavior of AppArmor in any way. This change explains the bulk of the diffstat beyond security/. - Fix a problem where we were not properly terminating the permission list for two SELinux object classes. * tag 'selinux-pr-20210426' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: add proper NULL termination to the secclass_map permissions smack: differentiate between subjective and objective task credentials selinux: clarify task subjective and objective credentials lsm: separate security_task_getsecid() into subjective and objective variants nfs: account for selinux security context when deciding to share superblock nfs: remove unneeded null check in nfs_fill_super() lsm,selinux: add new hook to compare new mount to an existing mount selinux: fix misspellings using codespell tool selinux: fix misspellings using codespell tool selinux: measure state and policy capabilities selinux: Allow context mounts for unpriviliged overlayfs
2021-04-22LSM: Infrastructure management of the superblockCasey Schaufler
Move management of the superblock->sb_security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules, the modules tell the infrastructure how much space is required, and the space is allocated there. Cc: John Johansen <john.johansen@canonical.com> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com> Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com> Acked-by: Serge Hallyn <serge@hallyn.com> Reviewed-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20210422154123.13086-6-mic@digikod.net Signed-off-by: James Morris <jamorris@linux.microsoft.com>
2021-04-09Merge tag 'selinux-pr-20210409' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux Pull selinux fixes from Paul Moore: "Three SELinux fixes. These fix known problems relating to (re)loading SELinux policy or changing the policy booleans, and pass our test suite without problem" * tag 'selinux-pr-20210409' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: fix race between old and new sidtab selinux: fix cond_list corruption when changing booleans selinux: make nslot handling in avtab more robust
2021-04-07selinux: fix race between old and new sidtabOndrej Mosnacek
Since commit 1b8b31a2e612 ("selinux: convert policy read-write lock to RCU"), there is a small window during policy load where the new policy pointer has already been installed, but some threads may still be holding the old policy pointer in their read-side RCU critical sections. This means that there may be conflicting attempts to add a new SID entry to both tables via sidtab_context_to_sid(). See also (and the rest of the thread): https://lore.kernel.org/selinux/CAFqZXNvfux46_f8gnvVvRYMKoes24nwm2n3sPbMjrB8vKTW00g@mail.gmail.com/ Fix this by installing the new policy pointer under the old sidtab's spinlock along with marking the old sidtab as "frozen". Then, if an attempt to add new entry to a "frozen" sidtab is detected, make sidtab_context_to_sid() return -ESTALE to indicate that a new policy has been installed and that the caller will have to abort the policy transaction and try again after re-taking the policy pointer (which is guaranteed to be a newer policy). This requires adding a retry-on-ESTALE logic to all callers of sidtab_context_to_sid(), but fortunately these are easy to determine and aren't that many. This seems to be the simplest solution for this problem, even if it looks somewhat ugly. Note that other places in the kernel (e.g. do_mknodat() in fs/namei.c) use similar stale-retry patterns, so I think it's reasonable. Cc: stable@vger.kernel.org Fixes: 1b8b31a2e612 ("selinux: convert policy read-write lock to RCU") Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-03-22Merge tag 'selinux-pr-20210322' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux Pull selinux fixes from Paul Moore: "Three SELinux patches: - Fix a problem where a local variable is used outside its associated function. Thankfully this can only be triggered by reloading the SELinux policy, which is a restricted operation for other obvious reasons. - Fix some incorrect, and inconsistent, audit and printk messages when loading the SELinux policy. All three patches are relatively minor and have been through our testing with no failures" * tag 'selinux-pr-20210322' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinuxfs: unify policy load error reporting selinux: fix variable scope issue in live sidtab conversion selinux: don't log MAC_POLICY_LOAD record on failed policy load
2021-03-18selinux: fix variable scope issue in live sidtab conversionOndrej Mosnacek
Commit 02a52c5c8c3b ("selinux: move policy commit after updating selinuxfs") moved the selinux_policy_commit() call out of security_load_policy() into sel_write_load(), which caused a subtle yet rather serious bug. The problem is that security_load_policy() passes a reference to the convert_params local variable to sidtab_convert(), which stores it in the sidtab, where it may be accessed until the policy is swapped over and RCU synchronized. Before 02a52c5c8c3b, selinux_policy_commit() was called directly from security_load_policy(), so the convert_params pointer remained valid all the way until the old sidtab was destroyed, but now that's no longer the case and calls to sidtab_context_to_sid() on the old sidtab after security_load_policy() returns may cause invalid memory accesses. This can be easily triggered using the stress test from commit ee1a84fdfeed ("selinux: overhaul sidtab to fix bug and improve performance"): ``` function rand_cat() { echo $(( $RANDOM % 1024 )) } function do_work() { while true; do echo -n "system_u:system_r:kernel_t:s0:c$(rand_cat),c$(rand_cat)" \ >/sys/fs/selinux/context 2>/dev/null || true done } do_work >/dev/null & do_work >/dev/null & do_work >/dev/null & while load_policy; do echo -n .; sleep 0.1; done kill %1 kill %2 kill %3 ``` Fix this by allocating the temporary sidtab convert structures dynamically and passing them among the selinux_policy_{load,cancel,commit} functions. Fixes: 02a52c5c8c3b ("selinux: move policy commit after updating selinuxfs") Cc: stable@vger.kernel.org Tested-by: Tyler Hicks <tyhicks@linux.microsoft.com> Reviewed-by: Tyler Hicks <tyhicks@linux.microsoft.com> Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> [PM: merge fuzz in security.h and services.c] Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-03-08selinux: measure state and policy capabilitiesLakshmi Ramasubramanian
SELinux stores the configuration state and the policy capabilities in kernel memory. Changes to this data at runtime would have an impact on the security guarantees provided by SELinux. Measuring this data through IMA subsystem provides a tamper-resistant way for an attestation service to remotely validate it at runtime. Measure the configuration state and policy capabilities by calling the IMA hook ima_measure_critical_data(). To enable SELinux data measurement, the following steps are required: 1, Add "ima_policy=critical_data" to the kernel command line arguments to enable measuring SELinux data at boot time. For example, BOOT_IMAGE=/boot/vmlinuz-5.11.0-rc3+ root=UUID=fd643309-a5d2-4ed3-b10d-3c579a5fab2f ro nomodeset security=selinux ima_policy=critical_data 2, Add the following rule to /etc/ima/ima-policy measure func=CRITICAL_DATA label=selinux Sample measurement of SELinux state and policy capabilities: 10 2122...65d8 ima-buf sha256:13c2...1292 selinux-state 696e...303b Execute the following command to extract the measured data from the IMA's runtime measurements list: grep "selinux-state" /sys/kernel/security/integrity/ima/ascii_runtime_measurements | tail -1 | cut -d' ' -f 6 | xxd -r -p The output should be a list of key-value pairs. For example, initialized=1;enforcing=0;checkreqprot=1;network_peer_controls=1;open_perms=1;extended_socket_class=1;always_check_network=0;cgroup_seclabel=1;nnp_nosuid_transition=1;genfs_seclabel_symlinks=0; To verify the measurement is consistent with the current SELinux state reported on the system, compare the integer values in the following files with those set in the IMA measurement (using the following commands): - cat /sys/fs/selinux/enforce - cat /sys/fs/selinux/checkreqprot - cat /sys/fs/selinux/policy_capabilities/[capability_file] Note that the actual verification would be against an expected state and done on a separate system (likely an attestation server) requiring "initialized=1;enforcing=1;checkreqprot=0;" for a secure state and then whatever policy capabilities are actually set in the expected policy (which can be extracted from the policy itself via seinfo, for example). Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com> Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com> Suggested-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-02-21Merge tag 'integrity-v5.12' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity Pull IMA updates from Mimi Zohar: "New is IMA support for measuring kernel critical data, as per usual based on policy. The first example measures the in memory SELinux policy. The second example measures the kernel version. In addition are four bug fixes to address memory leaks and a missing 'static' function declaration" * tag 'integrity-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity: integrity: Make function integrity_add_key() static ima: Free IMA measurement buffer after kexec syscall ima: Free IMA measurement buffer on error IMA: Measure kernel version in early boot selinux: include a consumer of the new IMA critical data hook IMA: define a builtin critical data measurement policy IMA: extend critical data hook to limit the measurement based on a label IMA: limit critical data measurement based on a label IMA: add policy rule to measure critical data IMA: define a hook to measure kernel integrity critical data IMA: add support to measure buffer data hash IMA: generalize keyring specific measurement constructs evm: Fix memleak in init_desc
2021-01-14selinux: include a consumer of the new IMA critical data hookLakshmi Ramasubramanian
SELinux stores the active policy in memory, so the changes to this data at runtime would have an impact on the security guarantees provided by SELinux. Measuring in-memory SELinux policy through IMA subsystem provides a secure way for the attestation service to remotely validate the policy contents at runtime. Measure the hash of the loaded policy by calling the IMA hook ima_measure_critical_data(). Since the size of the loaded policy can be large (several MB), measure the hash of the policy instead of the entire policy to avoid bloating the IMA log entry. To enable SELinux data measurement, the following steps are required: 1, Add "ima_policy=critical_data" to the kernel command line arguments to enable measuring SELinux data at boot time. For example, BOOT_IMAGE=/boot/vmlinuz-5.10.0-rc1+ root=UUID=fd643309-a5d2-4ed3-b10d-3c579a5fab2f ro nomodeset security=selinux ima_policy=critical_data 2, Add the following rule to /etc/ima/ima-policy measure func=CRITICAL_DATA label=selinux Sample measurement of the hash of SELinux policy: To verify the measured data with the current SELinux policy run the following commands and verify the output hash values match. sha256sum /sys/fs/selinux/policy | cut -d' ' -f 1 grep "selinux-policy-hash" /sys/kernel/security/integrity/ima/ascii_runtime_measurements | tail -1 | cut -d' ' -f 6 Note that the actual verification of SELinux policy would require loading the expected policy into an identical kernel on a pristine/known-safe system and run the sha256sum /sys/kernel/selinux/policy there to get the expected hash. Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com> Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com> Acked-by: Paul Moore <paul@paul-moore.com> Reviewed-by: Tyler Hicks <tyhicks@linux.microsoft.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-01-12selinux: drop the unnecessary aurule_callback variableOndrej Mosnacek
Its value is actually not changed anywhere, so it can be substituted for a direct call to audit_update_lsm_rules(). Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2020-10-27selinux: allow dontauditx and auditallowx rules to take effect without allowxbauen1
This allows for dontauditing very specific ioctls e.g. TCGETS without dontauditing every ioctl or granting additional permissions. Now either an allowx, dontauditx or auditallowx rules enables checking for extended permissions. Signed-off-by: Jonathan Hettwer <j2468h@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2020-09-11selinux: access policycaps with READ_ONCE/WRITE_ONCEStephen Smalley
Use READ_ONCE/WRITE_ONCE for all accesses to the selinux_state.policycaps booleans to prevent compiler mischief. Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2020-08-31selinux: simplify away security_policydb_len()Ondrej Mosnacek
Remove the security_policydb_len() calls from sel_open_policy() and instead update the inode size from the size returned from security_read_policy(). Since after this change security_policydb_len() is only called from security_load_policy(), remove it entirely and just open-code it there. Also, since security_load_policy() is always called with policy_mutex held, make it dereference the policy pointer directly and drop the unnecessary RCU locking. Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2020-08-27selinux: move policy mutex to selinux_state, use in lockdep checksStephen Smalley
Move the mutex used to synchronize policy changes (reloads and setting of booleans) from selinux_fs_info to selinux_state and use it in lockdep checks for rcu_dereference_protected() calls in the security server functions. This makes the dependency on the mutex explicit in the code rather than relying on comments. Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2020-08-26selinux: fix error handling bugs in security_load_policy()Dan Carpenter
There are a few bugs in the error handling for security_load_policy(). 1) If the newpolicy->sidtab allocation fails then it leads to a NULL dereference. Also the error code was not set to -ENOMEM on that path. 2) If policydb_read() failed then we call policydb_destroy() twice which meands we call kvfree(p->sym_val_to_name[i]) twice. 3) If policydb_load_isids() failed then we call sidtab_destroy() twice and that results in a double free in the sidtab_destroy_tree() function because entry.ptr_inner and entry.ptr_leaf are not set to NULL. One thing that makes this code nice to deal with is that none of the functions return partially allocated data. In other words, the policydb_read() either allocates everything successfully or it frees all the data it allocates. It never returns a mix of allocated and not allocated data. I re-wrote this to only free the successfully allocated data which avoids the double frees. I also re-ordered selinux_policy_free() so it's in the reverse order of the allocation function. Fixes: c7c556f1e81b ("selinux: refactor changing booleans") Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> [PM: partially merged by hand due to merge fuzz] Signed-off-by: Paul Moore <paul@paul-moore.com>
2020-08-25selinux: convert policy read-write lock to RCUStephen Smalley
Convert the policy read-write lock to RCU. This is significantly simplified by the earlier work to encapsulate the policy data structures and refactor the policy load and boolean setting logic. Move the latest_granting sequence number into the selinux_policy structure so that it can be updated atomically with the policy. Since removing the policy rwlock and moving latest_granting reduces the selinux_ss structure to nothing more than a wrapper around the selinux_policy pointer, get rid of the extra layer of indirection. At present this change merely passes a hardcoded 1 to rcu_dereference_check() in the cases where we know we do not need to take rcu_read_lock(), with the preceding comment explaining why. Alternatively we could pass fsi->mutex down from selinuxfs and apply a lockdep check on it instead. Based in part on earlier attempts to convert the policy rwlock to RCU by Kaigai Kohei [1] and by Peter Enderborg [2]. [1] https://lore.kernel.org/selinux/6e2f9128-e191-ebb3-0e87-74bfccb0767f@tycho.nsa.gov/ [2] https://lore.kernel.org/selinux/20180530141104.28569-1-peter.enderborg@sony.com/ Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
2020-08-19selinux: avoid dereferencing the policy prior to initializationStephen Smalley
Certain SELinux security server functions (e.g. security_port_sid, called during bind) were not explicitly testing to see if SELinux has been initialized (i.e. initial policy loaded) and handling the no-policy-loaded case. In the past this happened to work because the policydb was statically allocated and could always be accessed, but with the recent encapsulation of policy state and conversion to dynamic allocation, we can no longer access the policy state prior to initialization. Add a test of !selinux_initialized(state) to all of the exported functions that were missing them and handle appropriately. Fixes: 461698026ffa ("selinux: encapsulate policy state, refactor policy load") Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org> Tested-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>