Slowroll problem when installing SELinux

I ungraded my Leap 15.6 to Slowroll, not without issues but essentially I am there. However when I tried to install SELinux I ran into problems which are well beyond my paygrade! This is what I have:-
Slowroll on Btrfs, enabling SELinux in permissive after migration.
System boots and logs in, but AVCs show many accesses to unlabeled_t.
Investigation shows:

  • /usr is correctly labeled usr_t
  • /usr/lib64 is correctly labeled lib_t
  • the mounted Btrfs root subvolume @ itself has security.selinux=unlabeled_t
  • machine is usable on Plasma X11
    Question: what is the correct openSUSE-supported way to relabel the Btrfs root subvolume object itself, without reinstalling?
alastair@ibmserv2:~> sudo getenforce
[sudo] password for alastair: 
Permissive
alastair@ibmserv2:~> 
alastair@ibmserv2:~> 
alastair@ibmserv2:~> sudo ausearch -m AVC -ts boot | head -40
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.390:535): avc:  denied  { read } for  pid=1077 comm="dbus-broker-lau" name="lib64" dev="nvme0n1p1" ino=3100382 scontext=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:unlabeled_t:s0 tclass=lnk_file permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.727:554): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.727:555): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.727:556): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.727:557): avc:  denied  { read } for  pid=1132 comm="mcelog" name="lib64" dev="nvme0n1p1" ino=3100382 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=lnk_file permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.727:558): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.727:559): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.727:560): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.727:561): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.729:562): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.729:563): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.729:564): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 16:31:36 2026
type=AVC msg=audit(1774971096.729:565): avc:  denied  { search } for  pid=1132 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
alastair@ibmserv2:~> 

alastair@ibmserv2:~> sudo getfattr -n security.selinux -e text /mnt/btrfs-top/@ /mnt/btrfs-top/@/usr 2>/dev/null
[sudo] password for alastair: 
# file: mnt/btrfs-top/@
security.selinux="system_u:object_r:unlabeled_t:s0"

# file: mnt/btrfs-top/@/usr
security.selinux="system_u:object_r:usr_t:s0"

alastair@ibmserv2:~> sudo matchpathcon / /usr /usr/lib64 /etc/selinux
/       system_u:object_r:root_t:s0
/usr    system_u:object_r:usr_t:s0
/usr/lib64      system_u:object_r:lib_t:s0
/etc/selinux    system_u:object_r:selinux_config_t:s0
alastair@ibmserv2:~> 

Grateful for any guidance please.

Relabeling your system might help:
https://en.opensuse.org/Portal:SELinux/Troubleshooting#Relabeling_your_system

Hi Hui,
Your link is relevant, but in my case I have already gone a bit beyond the generic advice, because on ibmserv2 I found something more specific:

  • the Btrfs subvolume root @ is showing unlabeled_t
  • while paths under it like /usr are correctly labeled

That is why a normal /.autorelabel did not seem to finish the job on ibmserv2, whereas ibmserv3 was fixable by correcting the bad home-directory labels. That last part is my diagnosis from the machine state, not from the wiki page.
OTOH I think I missed the initrd part. Will look again.

I ran initrd and then autorelabel but I am still getting:-

alastair@ibmserv2:~> sudo getenforce
[sudo] password for alastair: 
Permissive
alastair@ibmserv2:~> sudo ausearch -m AVC -ts boot | head -40
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.251:947): avc:  denied  { read } for  pid=1399 comm="dbus-broker-lau" name="lib64" dev="nvme0n1p1" ino=3100382 scontext=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:unlabeled_t:s0 tclass=lnk_file permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.421:965): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.421:966): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.421:967): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.421:968): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.421:969): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.421:970): avc:  denied  { read } for  pid=1453 comm="mcelog" name="lib64" dev="nvme0n1p1" ino=3100382 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=lnk_file permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.421:971): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.421:972): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.421:973): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.423:974): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.423:975): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
time->Tue Mar 31 18:38:00 2026
type=AVC msg=audit(1774978680.424:976): avc:  denied  { search } for  pid=1453 comm="mcelog" name="@" dev="nvme0n1p1" ino=256 scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=dir permissive=1
----
alastair@ibmserv2:~> 

Now I am stuck and need guidance please.

Had a quick look: there is no label defined for /mnt/* in the selinux policy by default:

$ semanage fcontext -l | grep mnt
[..]
/mnt/(.*/)?\.snapshots/[^/]*/snapshot(/.*)?        all files          <<None>>
/mnt/[^/]*/.*                                      all files          <<None>>

If you run restorecon manually (i.e. to confirm) it should look like this:

$ restorecon -Rnv /mnt/btrfs-top/@
Warning no default label for /mnt/btrfs-top/@

The expectation is that the administrator needs to set the label or equivalence manually, but to give hints here what label to use it kinda though. Can you provide more context what data is stored there and how it is used ? Especially what sort of daemon is going to access the data and therefor might need specific labels set on the data to access it ?

What solutions does

ausearch -m AVC -ts boot | audit2allow

suggest?

Nothing you want because it’s going to suggest a whole lot of unlabled transitions.

Please provide the command output.

Hi and thanks for the reply. As will be evidenced by all my posts on this site I am not a coder and well out of my depth. I have been trying to switch to using SELinux on all my machines, all of which run and have run various versions of openSUSE for years. I started with upgrading Leap 15.6 machines, one to Leap 16.0 and one to Slowroll. I then tried to install SELinux and this is where I ran into the problem when attempting to check before changing permissive to enforce.
From my position of ignorance it seems all the subvolumes which are created and are essentially part of the btrfs system are throwing up this problem and it should have been handled by the migration tool. With a good deal of time and the help og ChatGPT I am posting the solution I have adopted. Please forgive me if through innocence I am breaking accepted norms!
Subject: Slowroll + SELinux on Btrfs: unlabeled root subvolume @ after migration, how I fixed it

I am posting this in case it helps anyone else.

I migrated a machine (ibmserv2) to openSUSE Slowroll on Btrfs, then later enabled SELinux. The machine would boot in Permissive, but ausearch -m AVC -ts boot showed many AVCs involving unlabeled_t.

The important point was that this was not a general SELinux policy problem and not something to solve with audit2allow. It was a labeling problem.

Symptoms

getenforce showed:

Permissive

AVCs looked like this:

avc: denied { read } ... tcontext=system_u:object_r:unlabeled_t:s0 ...

Initially the AVCs mentioned the Btrfs root subvolume object @ and root-level symlinks such as /bin, /lib, /sbin, /lib64.

What I found

The running system is mounted from the Btrfs subvolume @, so to inspect the real subvolume root object I mounted subvolid=5 temporarily:

sudo mkdir -p /mnt/btrfs-top
sudo mount -o subvolid=5 /dev/nvme0n1p1 /mnt/btrfs-top

Then I checked labels:

sudo getfattr -n security.selinux -e text /mnt/btrfs-top/@ /mnt/btrfs-top/@/usr 2>/dev/null
sudo matchpathcon / /usr /usr/lib64 /etc/selinux

This showed:

  • /mnt/btrfs-top/@ had unlabeled_t
  • /mnt/btrfs-top/@/usr was correctly labeled
  • later I also found the symlinks /mnt/btrfs-top/@/bin, /lib, /sbin, /lib64 needed fixing

So the real issue was the Btrfs subvolume root and root symlinks, not the whole tree.

Why /mnt/btrfs-top was needed

This was only a temporary tool to expose the top-level Btrfs tree so the real @ object could be inspected and labeled.

It is not part of the permanent fix and can be removed later.

Fix that worked for me

First I staged SELinux in the normal way:

sudo zypper in -t pattern selinux
sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config

GRUB kernel line needed:

security=selinux selinux=1 enforcing=0

Then:

sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo dracut --regenerate-all --force
sudo touch /.autorelabel
sudo reboot

That got the machine booting in Permissive, but the unlabeled_t problem remained.

The targeted fix was:

sudo mount -o subvolid=5 /dev/nvme0n1p1 /mnt/btrfs-top
sudo chcon -t root_t /mnt/btrfs-top/@
sudo chcon -h -t bin_t /mnt/btrfs-top/@/bin
sudo chcon -h -t lib_t /mnt/btrfs-top/@/lib
sudo chcon -h -t bin_t /mnt/btrfs-top/@/sbin
sudo chcon -h -t lib_t /mnt/btrfs-top/@/lib64
sudo reboot

After that, ausearch -m AVC -ts boot | head -40 dropped from many unlabeled_t AVCs to just one minor unrelated AVC.

Current state

The machine now boots with:

getenforce
Permissive

and the large unlabeled flood is gone.

I have not moved this machine to Enforcing yet, but it is now in a usable SELinux state.

Important note

/mnt/btrfs-top was only a temporary mountpoint. Once the work was done, it could be removed with:

sudo umount /mnt/btrfs-top
sudo rmdir /mnt/btrfs-top

This does not undo the labels already written to the Btrfs objects.

My conclusion

This looks like a Btrfs subvolume-root labeling issue that appeared after migration / later SELinux enablement. It does not seem to be something that should be fixed by audit2allow.

If anyone knows a cleaner or more official openSUSE-supported way to relabel the Btrfs root subvolume object itself, I would still be interested.

1 Like

Please provide the command output.

So you don’t understand what audit2allow does?

All it does is look at the current denies and produces a module to allow it. No idea if it should, if it’s the right thing or if you’re about to shoot yourself in the foot. At best it might hint that there is a boolean you could turn on to allow the actions, but it’s purpose is to set up rules to allow what is being denied.

So given a series of denies like this scontext=system_u:system_r:mcelog_t:s0 tcontext=system_u:object_r:unlabeled_t:s0

All it’s going to do is create a rule to allow them. Confined to unconfined is always wrong because what it shows is you have a context label issue.

If your goal is to just shut these messages up, throwing audit2allow at this will do it, but setting SELinux to disabled would be faster and you wouldn’t have to keep going back to create more policies in the future.

Not to much into btrfs details…, so take with a grain of salt

That looks like a wrong AI suggestions to me then, based off [0], and should have been multiple instances of:

sudo mount -o subvol=/@/<SOME FOLDER> /dev/nvme0n1p1 /mnt/btrfs-top/<SOME FOLDER>

In general the migration tool should label everything correctly after the first boot in permissive. The magic ‘@’ folder should never be mounted/visible in the system as it is some btrfs interna.

The ‘proper way’ IMO is to edit /etc/selinux/config: SELINUX=permissive, touch /etc/selinux/.autorelabel (or one of the other locations like /.autorelabel) and reboot. The more extended description can be found here [1].

[0] https://archive.kernel.org/oldwiki/btrfs.wiki.kernel.org/index.php/SysadminGuide.html#Subvolumes
[1] https://en.opensuse.org/Portal:SELinux/Setup#Tumbleweed

@rfrohl:

??? Here on Tumbleweed:

 # semanage fcontext --list | grep '/mnt'
/mnt(/[^/]*)?                                      directory          system_u:object_r:mnt_t:s0 
/mnt(/[^/]*)?                                      symbolic link      system_u:object_r:mnt_t:s0 
/mnt/(.*/)?\.snapshots(/.*)?                       all files          system_u:object_r:snapperd_data_t:s0 
/mnt/(.*/)?\.snapshots/[^/]*/snapshot(/.*)?        all files          <<None>>
/mnt/[^/]*/.*                                      all files          <<None>>
 . 
 . 
 #

At least for the Tumbleweed policy, the “/mnt” directory does have a policy and “restorecon” will drop the appropriate policies on the directories below “/mnt” –

 > ls -aldZ /mnt
dr-xr-xr-x. 7 root root system_u:object_r:mnt_t:s0 4096 24. Jul 2025  /mnt
 > ls -aldZ /mnt/*
drwxr-xr-x. 2 root root system_u:object_r:mnt_t:s0    4096 10. Okt 2021  /mnt/Arbeitsverzeichnis-001
drwxr-xr-x. 2 root root system_u:object_r:mnt_t:s0    4096 21. Okt 2020  /mnt/Arbeitsverzeichnis-002
drwxr-xr-x. 2 root root system_u:object_r:autofs_t:s0    0  1. Apr 15:45 /mnt/NAS-Bureau-001
drwxr-xr-x. 2 root root system_u:object_r:mnt_t:s0    4096 20. Okt 2020  /mnt/Sicherungen
drwxr-xr-x. 2 root root system_u:object_r:mnt_t:s0    4096 24. Jul 2025  /mnt/Test-VM
 >

Yes you are correct that the folders in /mnt get labeled, should have phrased that a bit better. I was not clear about what the actual goal/use case was for the relabeling and wanted to get to the reason.

The general problem we discussed here was about mounting a file system and then assigning the correct labels in that mounted file system. Which would not have worked with restorecon or relabeling the filesystem through other means without intervention.

What makes you say that?

That is correct …

but only if asked to do so (did I?) and even if such a module is created audit2allow will not apply that module!

My goal is to gather as much information on OPs problem as possible (and not to rant based on assumptions).

Which is why I use “restorecon -F” to force the policy provided by SUSE and openSUSE …

But how would that have helped in the case described by Budgie2 ? restorecon assigns the file context based on the path, i.e. the current position in the directory tree:

If the disk, that was mounted under /mnt/*, is supposed to boot independently mounted under / that would assign the wrong labels as the files would be in a different position once the system boots.

If the disk would have stayed under /mnt then it would need manual intervention by the system admin to assign the correct labels based on the use case. For that case we did not have enough details to help provide the correct labels.

I am just trying to explain why it was the wrong approach to fix the problem so that it might help people in the future, I am not blaming anyone. I may also not fully understand your point about ‘restorecon -F’, because this is mentioned for the first time in this thread as far as I can tell.

If a file system is mounted for the first time somewhere – for example under ‘/mnt’ – then, “restorecon” with the “-F” option has to be run to force the correct context for that filesystem.
But, one should first read the semanage-fcontext man (8) page – especially the “EXAMPLE” section.
For the case of /mnt, my “SELinux Local fcontext Equivalence” list looks like this –

/mnt/Arbeitsverzeichnis-001/User-xxx = /home
/mnt/Arbeitsverzeichnis-002/User-xxx = /home
/mnt/Sicherungen/User-xxx = /home

If that filesystem were to be re-mounted somewhere else – for example directly on ‘/’ then, “restorecon” will have to be run again with the “-F” option to force the correct context for that filesystem.


Please be aware that, automatically relabelling the machine’s entire filesystem on reboot, is fine only for the case of small systems with at most only a Terabyte or so of physical disk space – if the machine is a database server with Petabytes of physical disk space, the automatic relabelling will cause an unacceptable reboot time needed before the system can be put online again.

My conclusion is that although I went about it manually and not the preferred method I have ended up with the intended and correct system.
My mistake was not using the migration tool but at the time I was not aware it was available.
My thanks to all who have contributed. Forewarned, I am now going to use the migration tool to change my laptop Tumbleweed to Slowroll as I believe it is more appropriate on that machine.
Thanks again,
Budge