19 Dec 2024 tags: audit lsm selinux This post is a bit later than normal, my apologies for that, but Linux v6.12 was released on Sunday, November 17th with the Linux v6.13 merge window opening immediately afterwards. Below are the highlights of the LSM, SELinux, and Audit pull requests which have been merged into Linus’ tree.
LSM
-
Start the process of moving away from the existing secid
integer LSM identifier in the kernel towards a richer lsm_prop
structure. This change will enable us to remove some of the translation steps that are necessary in many LSMs when interacting with the rest of the Linux kernel, and should make is easier to support different LSMs in the future.
-
Decouple the fsnotify subsystem from the LSM, allowing the two subsystems to be selected independently from one another when building the Linux kernel.
SELinux
- In Linux v4.3 we introduced the concept of “extended permissions” to enable SELinux to enforce access controls on individual ioctl(2) commands. Starting in Linux v6.13 administrators will now also be able to use the extended permission functionality to enforce access controls on individual netlink(7) messages. Thiébaud Weksteen, the patch’s author, provides some additional information and examples in the commit description:
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:
- This is similar to the other extended permission (“ioctl”);
- 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.
- Having a single extra extended permission considerably simplifies the implementation here and in libselinux.
- The “/sys/fs/selinux/user” interface has been marked as deprecated in the kernel. The deprecation notice provides some additional information:
The selinuxfs “user” node allows userspace to request a list of security contexts that can be reached for a given SELinux user from a given starting context. This was used by libselinux when various login-style programs requested contexts for users, but libselinux stopped using it in 2020. Kernel support will be removed no sooner than Dec 2025.
- Cleaned the SELinux build scripts and tooling. We relocated the “genheaders” tool to the “security/selinux” directory and corrected our usage of kernel headers to make it easier to build the Linux kernel on different systems.
Audit
- Minor cleanups involving corrections to the kdoc function parameters and increased usage of the
str_yes_no()
kernel helper function.
06 Dec 2024 tags: audit lsm selinux Linux v6.12 was released on Sunday, November 17th. I already wrote up a post highlighting the LSM, SELinux, and audit changes that were submitted during the merge window, however there were additional changes that went in during the release candidate process which are described below.
LSM
-
Add a missing security_mmap_file()
LSM hook call to the remap_file_pages(2) syscall. This helps ensure that the LSM-based access controls for memory pages are properly enforced.
-
Fixed a problem where the IPE kernel selftests could result in a crash due to a missing unit test list terminator.
-
Constification of the path parameter in the security_bpf_token_create()
LSM hook.
SELinux
- Fix a problem in the SELinux access controls for the kernel keyrings where they were not properly converted to the new LSM object lifecycle scheme that was merged during the Linux v6.12 merge window.
In addition to my highlights, LWN.net provides a nice overall summary of the kernel changes made during the first and second weeks of the merge window.
19 Sep 2024 tags: audit lsm selinux Linux v6.11 was released on Sunday, with the Linux v6.12 merge window opening immediately afterwards. Below are the highlights of the LSM, SELinux, and Audit pull requests which have been merged into Linus’ tree.
LSM
-
Introduce the Integrity Policy Enforcement (IPE) LSM. IPE provides a mechanism that administrators can use to restrict execution to only those binaries which come from integrity protected storage, e.g. a dm-verity protected filesystem. The IPE patchset included a good deal of documentation on how IPE works as well as how to configure it, once Linux v6.12 is released the documentation should be available for viewing online.
-
Convert the LSM framework to use static calls instead of the traditional function pointer approach, which should result in a modest performance improvement for most workloads. While the vast majority of the LSM callbacks are now done with static calls, there are a few which continue to use function pointers due to the complexity involved; we may revisit that effort in a future Linux kernel release.
-
Move the lifecycle management of the various kernel object’s LSM state from the individual LSMs to the LSM framework itself. Not only does this help eliminate a lot of redundant code across the LSMs, it makes it much easier to properly support multiple simultaneous LSMs. All of the LSM kernel object state is now managed by the LSM framework with the exception of the XFRM (IPsec) LSM state, which was skipped due to its complexity, we may revisit LSM state management for XFRM objects in the future.
-
Fix problems with the F_SETOWN fcntl(2) operator where the LSM was not properly protected against race conditions and not synchronized with the discretionary access control logic. This could result in incorrect or invalid F_SETOWN LSM state attached to a file descriptor.
-
Fix a potential problem relating to how the LSM interacts with the VFS subsystem when an inode is freed. Due to complexities in the inode locking mechanisms, notably the use of RCU, and the placement of the LSM hook associated with freeing the inode, an additional LSM callback was added to the security_inode_free()
LSM hook. This allows LSMs to have a callbacks both when the inode is initially marked for release, via call_rcu()
or similar, and when the associated LSM state is safe to be freed.
-
Two LSM hooks, security_inode_copy_up_xattr()
and security_vm_enough_memory_mm()
were refactored to follow the common Linux kernel convention of returning 0 on success and negative error codes on failure. This change not only helps prevent accidental misuse or bad interpretations of these hook’s return values, it also helps the eBPF verifier verify that BPF LSM programs are “safe” to execute.
-
A number of small cleanups and minor improvements to remove redundant code, make better use of helper functions, and fix coding style problems.
SELinux
-
Fix a bug where SELinux did not properly initialize the NetLabel socket state for IPv6 connections.
-
Annotate the SELinux inode initialization code to avoid a spurious KCSAN warning.
-
A number of small cleanups and minor improvements to simplify some SELinux logic and fix some minor coding style problems.
Audit
- Finish the transition to using the kernel Thread Group ID (TGID) in place of the normal Process ID (PID) in the audit logs and filters. In almost all cases the TGID is what most users think of when they think of a PID, as explained in the getpid(2) manpage:
From a kernel perspective, the PID (which is shared by all of the threads in a multithreaded process) is sometimes also known as the thread group ID (TGID).