[LTP] [PATCH v4 1/2] core: add tst_selinux_enabled() utility

Stephen Smalley stephen.smalley.work@gmail.com
Tue Jul 22 15:20:30 CEST 2025


On Tue, Jul 22, 2025 at 9:18 AM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> On Tue, Jul 22, 2025 at 8:06 AM Petr Vorel <pvorel@suse.cz> wrote:
> >
> > Hi Andrea, all,
> >
> > [ Cc Stephen, the fix author in case I'm wrong with reproducing on enforcing=0 ]
> >
> > > Add tst_selinux_enabled() utility in tst_security.h in order to verify
> > > if SELinux is currently up and running in the system.
> > ...
> > > +int tst_selinux_enabled(void)
> > > +{
> > > +     int res = 0;
> > > +
> > > +     if (tst_is_mounted(SELINUX_PATH))
> > > +             res = 1;
> >
> > I was wondering if it the test require enforcing or not therefore I retested it
> > and it's really reproducible with permissive mode, i.e. with kernel command line
> > security=selinux selinux=1 enforcing=0
> >
> > Because if enforcing was required, I would be for using tst_selinux_enforcing(),
> > which checks /sys/fs/selinux/enforce for 1 as Wei suggested in v3:
> >
> > https://lore.kernel.org/ltp/aHf839WS0BPIa5Zq@MiWiFi-CR6608-srv/
> >
> > @Cyril @Andrea, just checking if /sys/fs/selinux/enforce exists would be faster
> > than looping /proc/mounts (via tst_is_mounted(SELINUX_PATH)). Can we just modify
> > the patch?
>
> Not sure if I have the full context, but modern libselinux has this
> for is_selinux_enabled():
>
> int is_selinux_enabled(void)
> {
>         /* init_selinuxmnt() gets called before this function. We
>          * will assume that if a selinux file system is mounted, then
>          * selinux is enabled. */
> #ifdef ANDROID
>         return (selinux_mnt ? 1 : 0);
> #else
>         return (selinux_mnt && has_selinux_config);
> #endif
> }
>
> And init_selinuxmnt(), a constructor for libselinux, does this:
>
> static void init_selinuxmnt(void)
> {
>         char *buf = NULL, *p;
>         FILE *fp = NULL;
>         size_t len;
>         ssize_t num;
>
>         if (selinux_mnt)
>                 return;
>
>         if (verify_selinuxmnt(SELINUXMNT) == 0) return;
>
>         if (verify_selinuxmnt(OLDSELINUXMNT) == 0) return;
>
>         /* Drop back to detecting it the long way. */
>         if (!selinuxfs_exists())
>                 goto out;
> ...
>
> So in the common case we don't need to check /proc/mounts or
> /proc/filesystems, only if we don't find selinuxfs on one of the
> expected mount directories (/sys/fs/selinux or /selinux).

Also, for reference, verify_selinuxmnt() is as follows:

static int verify_selinuxmnt(const char *mnt)
{
        struct statfs sfbuf;
        int rc;

        do {
                rc = statfs(mnt, &sfbuf);
        } while (rc < 0 && errno == EINTR);
        if (rc == 0) {
                if ((uint32_t)sfbuf.f_type == (uint32_t)SELINUX_MAGIC) {
                        struct statvfs vfsbuf;
                        rc = statvfs(mnt, &vfsbuf);
                        if (rc == 0) {
                                if (!(vfsbuf.f_flag & ST_RDONLY)) {
                                        set_selinuxmnt(mnt);
                                }
                                return 0;
                        }
                }
        }

        return -1;
}

>
> >
> > Kind regards,
> > Petr
> >
> > +++ lib/tst_security.c
> > @@ -107,7 +107,7 @@ int tst_selinux_enabled(void)
> >  {
> >         int res = 0;
> >
> > -       if (tst_is_mounted(SELINUX_PATH))
> > +       if (access(SELINUX_STATUS_PATH, F_OK) == 0)
> >                 res = 1;
> >
> >         tst_res(TINFO, "SELinux enabled: %s", res ? "yes" : "no");


More information about the ltp mailing list