]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selinux: support wildcard network interface names
authorChristian Göttsche <cgzones@googlemail.com>
Sun, 2 Mar 2025 15:40:45 +0000 (16:40 +0100)
committerPaul Moore <paul@paul-moore.com>
Fri, 7 Mar 2025 20:11:10 +0000 (15:11 -0500)
Add support for wildcard matching of network interface names.  This is
useful for auto-generated interfaces, for example podman creates network
interfaces for containers with the naming scheme podman0, podman1,
podman2, ...

To maintain backward compatibility guard this feature with a new policy
capability 'netif_wildcard'.

Netifcon definitions are compared against in the order given by the
policy, so userspace tools should sort them in a reasonable order.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
security/selinux/include/policycap.h
security/selinux/include/policycap_names.h
security/selinux/include/security.h
security/selinux/ss/services.c

index 079679fe7254b0dcbdb9f634c3fd17275643d1de..bd402d3fd3ae977e9488fe30054f3bc2bef4f788 100644 (file)
@@ -15,6 +15,7 @@ enum {
        POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
        POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT,
        POLICYDB_CAP_NETLINK_XPERM,
+       POLICYDB_CAP_NETIF_WILDCARD,
        __POLICYDB_CAP_MAX
 };
 #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)
index e080827408c4c838383bd2bce1dba4b154e4cc8f..ac1342d6d5bb206e7d61413b17d1aac7b48be015 100644 (file)
@@ -18,6 +18,7 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
        "ioctl_skip_cloexec",
        "userspace_initial_context",
        "netlink_xperm",
+       "netif_wildcard",
 };
 /* clang-format on */
 
index 8b4c2aa358399202d450ded6be3e432e2b9c73d8..e7827ed7be5f1bd6cb5096a8771b57d4967ae896 100644 (file)
@@ -202,6 +202,12 @@ static inline bool selinux_policycap_netlink_xperm(void)
                selinux_state.policycap[POLICYDB_CAP_NETLINK_XPERM]);
 }
 
+static inline bool selinux_policycap_netif_wildcard(void)
+{
+       return READ_ONCE(
+               selinux_state.policycap[POLICYDB_CAP_NETIF_WILDCARD]);
+}
+
 struct selinux_policy_convert_data;
 
 struct selinux_load_state {
@@ -301,7 +307,7 @@ int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
 
 int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid);
 
-int security_netif_sid(char *name, u32 *if_sid);
+int security_netif_sid(const char *name, u32 *if_sid);
 
 int security_node_sid(u16 domain, void *addr, u32 addrlen, u32 *out_sid);
 
index 8478842fbf9ef919cff9457c082c7bf0f77e26ab..1b11648d9b8584a3320455a74707f969c3e52578 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/in.h>
 #include <linux/sched.h>
 #include <linux/audit.h>
+#include <linux/parser.h>
 #include <linux/vmalloc.h>
 #include <linux/lsm_hooks.h>
 #include <net/netlabel.h>
@@ -2572,19 +2573,22 @@ out:
  * @name: interface name
  * @if_sid: interface SID
  */
-int security_netif_sid(char *name, u32 *if_sid)
+int security_netif_sid(const char *name, u32 *if_sid)
 {
        struct selinux_policy *policy;
        struct policydb *policydb;
        struct sidtab *sidtab;
        int rc;
        struct ocontext *c;
+       bool wildcard_support;
 
        if (!selinux_initialized()) {
                *if_sid = SECINITSID_NETIF;
                return 0;
        }
 
+       wildcard_support = selinux_policycap_netif_wildcard();
+
 retry:
        rc = 0;
        rcu_read_lock();
@@ -2594,8 +2598,14 @@ retry:
 
        c = policydb->ocontexts[OCON_NETIF];
        while (c) {
-               if (strcmp(name, c->u.name) == 0)
-                       break;
+               if (wildcard_support) {
+                       if (match_wildcard(c->u.name, name))
+                               break;
+               } else {
+                       if (strcmp(c->u.name, name) == 0)
+                               break;
+               }
+
                c = c->next;
        }