summaryrefslogtreecommitdiff
path: root/security/selinux/nlmsgtab.c
diff options
context:
space:
mode:
authorThiébaud Weksteen <tweek@google.com>2024-09-12 11:45:03 +1000
committerPaul Moore <paul@paul-moore.com>2024-10-07 16:28:11 -0400
commitd1d991efaf34606d500dcbd28bedc0666eeec8e2 (patch)
treef081bde95340ed7e8c783d905c0ce93401a0441a /security/selinux/nlmsgtab.c
parent3b70b66e03b54428d45c3fe9b8693cffcde45bf6 (diff)
selinux: Add netlink xperm support
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>
Diffstat (limited to 'security/selinux/nlmsgtab.c')
-rw-r--r--security/selinux/nlmsgtab.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 8ff670cf1ee5..acc7d74b99d5 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -170,6 +170,33 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
{
int err = 0;
+ if (selinux_policycap_netlink_xperm()) {
+ switch (sclass) {
+ case SECCLASS_NETLINK_ROUTE_SOCKET:
+ *perm = NETLINK_ROUTE_SOCKET__NLMSG;
+ break;
+ case SECCLASS_NETLINK_TCPDIAG_SOCKET:
+ *perm = NETLINK_TCPDIAG_SOCKET__NLMSG;
+ break;
+ case SECCLASS_NETLINK_XFRM_SOCKET:
+ *perm = NETLINK_XFRM_SOCKET__NLMSG;
+ break;
+ case SECCLASS_NETLINK_AUDIT_SOCKET:
+ *perm = NETLINK_AUDIT_SOCKET__NLMSG;
+ break;
+ /* While it is possible to add a similar permission to other
+ * netlink classes, note that the extended permission value is
+ * matched against the nlmsg_type field. Notably,
+ * SECCLASS_NETLINK_GENERIC_SOCKET uses dynamic values for this
+ * field, which means that it cannot be added as-is.
+ */
+ default:
+ err = -ENOENT;
+ break;
+ }
+ return err;
+ }
+
switch (sclass) {
case SECCLASS_NETLINK_ROUTE_SOCKET:
/* RTM_MAX always points to RTM_SETxxxx, ie RTM_NEWxxx + 3.