Re: [PATCH v2] selinux: support wildcard match in genfscon

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 11 Mar 2025 at 17:23, Stephen Smalley
<stephen.smalley.work@xxxxxxxxx> wrote:
>
> On Tue, Mar 11, 2025 at 6:52 AM Christian Göttsche
> <cgzones@xxxxxxxxxxxxxx> wrote:
> >
> > Mar 11, 2025 10:29:42 Takaya Saeki <takayas@xxxxxxxxxxxx>:
> >
> > > Currently, genfscon only supports string prefix match to label files.
> > > Thus, labeling numerous dynamic sysfs entries requires many specific
> > > path rules. For example, labeling device paths such as
> > > `/sys/devices/pci0000:00/0000:00:03.1/<...>/0000:04:00.1/wakeup`
> > > requires listing all specific PCI paths, which is challenging to
> > > maintain. While user-space restorecon can handle these paths with
> > > regular expression rules, but relabeling thousands of paths under sysfs
> > > after it is mounted is inefficient compared to using genfscon.
> > >
> > > This commit adds wildcard match to support rules efficient but
> > > expressive enough. This allows users to create fine-grained sysfs rules
> > > without burden of listing specific paths. When multiple wildcard rules
> > > match against a path, then the longest rule (determined by the length of
> > > the rule string) will be applied. If multiple rules of the same length
> > > match, the first matching rule encountered in the genfscon policy will
> > > be applied. However, users are encouraged to write longer, more explicit
> > > path rules to avoid relying on this behavior.
> > >
> > > This change resulted in nice real-world performance improvements. For
> > > example, boot times on test Android devices were reduced by 15%. This
> > > improvement is due to the elimination of the "restorecon -R /sys" step
> > > during boot, which takes more than two seconds in the worst case.
> > >
> > > Signed-off-by: Takaya Saeki <takayas@xxxxxxxxxxxx>
> > > ---
> > > Changelog between v2 and v1
> > > - Use given genfs rules by the userspace as is, instead of appending "*".
> > > - Fix __security_genfs_sid hadn't checked caps of the given argument.
> > > - Fix the wrong strncmp usage bug.
> > >
> > > security/selinux/include/policycap.h       |  1 +
> > > security/selinux/include/policycap_names.h |  1 +
> > > security/selinux/ss/services.c             | 20 ++++++++++++++++----
> > > 3 files changed, 18 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/security/selinux/include/policycap.h b/security/selinux/include/policycap.h
> > > index 079679fe7254..2b4014a826f0 100644
> > > --- a/security/selinux/include/policycap.h
> > > +++ b/security/selinux/include/policycap.h
> > > @@ -15,6 +15,7 @@ enum {
> > >     POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
> > >     POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT,
> > >     POLICYDB_CAP_NETLINK_XPERM,
> > > +   POLICYDB_CAP_GENFS_SECLABEL_WILDCARD,
> > >     __POLICYDB_CAP_MAX
> > > };
> > > #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)
> > > diff --git a/security/selinux/include/policycap_names.h b/security/selinux/include/policycap_names.h
> > > index e080827408c4..1053f2c95ff3 100644
> > > --- a/security/selinux/include/policycap_names.h
> > > +++ b/security/selinux/include/policycap_names.h
> > > @@ -18,6 +18,7 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
> > >     "ioctl_skip_cloexec",
> > >     "userspace_initial_context",
> > >     "netlink_xperm",
> > > +   "genfs_seclabel_wildcard",
> > > };
> > > /* clang-format on */
> > >
> > > diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> > > index 8478842fbf9e..9f98c9dc71f6 100644
> > > --- a/security/selinux/ss/services.c
> > > +++ b/security/selinux/ss/services.c
> > > @@ -48,6 +48,7 @@
> > > #include <linux/audit.h>
> > > #include <linux/vmalloc.h>
> > > #include <linux/lsm_hooks.h>
> > > +#include <linux/parser.h>
> > > #include <net/netlabel.h>
> > >
> > > #include "flask.h"
> > > @@ -2863,6 +2864,7 @@ static inline int __security_genfs_sid(struct selinux_policy *policy,
> > >     struct genfs *genfs;
> > >     struct ocontext *c;
> > >     int cmp = 0;
> > > +   bool wildcard = 0;
> > >
> > >     while (path[0] == '/' && path[1] == '/')
> > >         path++;
> > > @@ -2879,11 +2881,21 @@ static inline int __security_genfs_sid(struct selinux_policy *policy,
> > >     if (!genfs || cmp)
> > >         return -ENOENT;
> > >
> > > +
> > > +   wildcard = ebitmap_get_bit(&policy->policydb.policycaps,
> > > +                  POLICYDB_CAP_GENFS_SECLABEL_WILDCARD);
> >
> > Commonly policy capabilities are gathered via a helper from security.h from selinux_state, shouldn't it here too?
>
> Those are for accessing the cached policy capabilities in the
> selinux_state from outside of the security server (and without holding
> any locks), e.g. from the hook functions.
> No need for that here, and this is more correct - using the policy we
> were passed rather than whatever selinux_state might reference at the
> time (e.g. during a policy reload).

Should this also be used in security_netif_sid()?


diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 1b11648d9b85..720a69fb4234 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2587,14 +2587,13 @@ int security_netif_sid(const char *name, u32 *if_sid)
               return 0;
       }

-       wildcard_support = selinux_policycap_netif_wildcard();
-
retry:
       rc = 0;
       rcu_read_lock();
       policy = rcu_dereference(selinux_state.policy);
       policydb = &policy->policydb;
       sidtab = policy->sidtab;
+       wildcard_support = ebitmap_get_bit(policydb->policycaps,
POLICYDB_CAP_NETIF_WILDCARD);

       c = policydb->ocontexts[OCON_NETIF];
       while (c) {





[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux