Build failed with SELinux

I've followed your advice and the compilation process seems great. The default file contexts and process contexts in the squashfs image also worked very well. (Although the ext4 image seems problematic)
But "semanage" is a quite common tool used in SELinux system. It seems that "semanage" is a neccessary tool to set file context and check whether SELinux actually works or not. So I came back and turn on the "Utilities -> selinux-semanage" option in menuconfig.

The compilation succeeded. The "sestatus" seems fine. But I still failed to execute "semanage login -l":

ValueError: SELinux policy is not managed or store cannot be accessed.

Failed to change a file context when I executed "semanage fcontext -a -t tmpfile.conftmpfile /tmp/file1":

ValueError: SELinux policy is not managed or store cannot be accessed.

btw, after I turned on all the SELinux-related options in "Utilities" like "libselinux-tools", the compilation worked fine, but the above mentioned commands still cannot work.

So, did the SELinux actually worked? Or did I missed something or used the wrong commands?

Thank you so much for your time! Looking forward to your reply.

Zijing

We are not using semanage, there is nothing to configure when using the dssp (which is the only truly supported way of using SELinux on OpenWrt).
It's really more like SELinux on Android than SELinux refpolicy running on RHEL. So no semanage, sebool, ...
Check if sestatus telling you it's 'enforcing', if so you succeeded.

Thank you for your reply!

Sad to hear that dssp policy cannot be customized by users. I was planning to try out some SELinux policies, doing experiment to make OpenWRT more secure.

If I want to figure out some new policies, is "targeted" mode(which is highly unusable) the only way to do so? Is there any chance that I can edit the policies contained in dssp? If so, how could I achieve that?

Can I change the policy inside the OpenWRT system after booting(without using semanage)? Or can I only change the policy outside the system, and then substitute the policy file contained in the original OpenWRT img, then flash that into the device?

Thank you so much for your time! Looking forward to your reply!

Zijing

You can customize dssp: here is a tutorial (although might be outdated) https://github.com/doverride/openwrt-selinux-policy/blob/master/README.md

The only difference is that changes are made at compile time and not at run time.

You can still use tools like chcon to set contexts on files, but semanage is a tool to customize the policy at run-time and that functionality is not supported. It cannot reasonably be supported due to the nature of the system (policy is loaded from read-only squashfs, wireless router devices generally lack resources to compile policy at run-time)

What issues did you encounter with dssp on ext4 image? SELinux will print its feedback to the kernel ring buffer, so you can grep that (dmesg | grep -i denied) and report those so that they can be interpreted and addressed.

You can surely customize dssp as well, just that happens at build-time and not dynamically during run-time as you may be used on non-embedded platforms.

Yes, something like that. Substituting only the policy file itself is usually not enough, as also labels are applied from the policy. I use CONFIG_SRC_TREE_OVERRIDE to build using a local git checkout of dssp policy I'm working on and then also labels from there are applied on the rootfs.

And yes, only squashfs is supported for now as that's what OpenWrt is mostly all about. Using rootfs filesystems other than squashfs is only intended for development/debugging.

Is there any kind of target restriction, I have not been able to get by thread

Thank you for your help!~
I've tried out some experiment. The basic allow/deny worked fine on ext4 image. The only problem encountered in ext4 was the insufficient default file context / process context.

For example, the default context of the root path in squashfs is:

But the default context of the root path in ext4 image is:

Same issue occurred in process context. This doesn't affect my study and some little experiment at the moment, since the basic allow/deny works fine. But I'm still a little bit worry about the reason why such default contexts cannot be applied correctly on files in ext4 image.

Could you please tell me the reason? Will this affect other SELinux utilities?

Thank you!

Zijing

Thank you so much for your help! That explains a lot! I'm going to try out some simple self-customized policies to start.

I truly appreciate your timely help!

Zijing

I'm not an expert on this, but I've encountered this problem before when I was trying to build images for MIPS architecture.

You can try turning off the "busybox" option in "Base system" in menuconfig, keep the auto-selected "busybox-selinux" only.

Turn off the "procd" in "Base system", keep only the auto-selected "procd-selinux":

Although I'm not an expert, and these are just some dummy experience-based suggestions, you can still give it a try~

Zijing

Seems that the build-system did not label the ext4 filesystem. I think this is a known issue that also happens when you use a tmpfs rootfs. As Daniel stated, the focus is on squashfs with overlay currently (but I do consider this to be a loose end that should eventually be addressed).

Obviously this will affect SELinux enforcement because the labels are incorrect. So, i guess for now it is safe to say that SELinux does not work reliably on images with ext4 and tmpfs rootfs.

The labels on your squashfs installation look fine, with the exception of the /boot mountpoint. Not sure why you even have a /boot mountpoint but regardless that minor issue should not affect operations. Do you have any filesystem mounted on /boot, if so: which? and why?

Thank you for your time!

I didn't mount anything on purpose. I was just using the squashfs-combined type of image. Seems like the loader component like "grub" is mounted on that. I guess this will not cause any extra problems, right?

Thanks for your help!

Zijing

should not cause any issues, but its not really pretty either.

is there any point to having that stuff though? I mean it boots from a read-only squashfs so you cannot edit /boot/grub/grub.cfg anyway and expect that to take affect on the next boot since at that point the overlay is not mounted yet.

Actually I'm a little bit confused too :joy::joy: But it just be mounted automatically when I use qemu to boot OpenWRT with something like:

sudo qemu-system-x86_64 -drive file=openwrt-x86-64-generic-squashfs-combined.img,format=raw,if=virtio -m 256 -nographic

and /boot is already mounted.

Zijing

Hi. I customized dssp based on the tutorial, which is well-written and easy to follow.

Specifically, I added some auditallow statements to observe the behavior of my program.
Due to the massive logs, I want to change the context of the running program (a process actually) to a new label/context auditing fewer operations, when the audit log reaches the amount limitation.

How can I do this——I mean how to change the context of a running process?
Any command or interesting idea? I really need your advice.
Thank you!

Contexts transitions generally either only happen on execve or create with automatic transition rules, manually with the runcon command or programmatically with the setcon() function: https://linux.die.net/man/3/setcon

I guess closest to what you are looking for would be setcon().

Depending on what you need this for there may be better solutions, like dontaudit and typepermissive statements, or customization to your logging configuration.

Thank you for this timely reply.

So as you said, I can only re-run the program with a different context, but can not change the context of the already running program. Do I understand right?

Besides, I fail to execute the ausearch command in the OpenWrt and get the following hint:

Config file /etc/audit/auditd.conf doesn't exist, skipping
Error opening /var/log/audit/audit.log (No such file or directory)

It seems that SELinux denial messages are logged to /var/log/audit/audit.log, but this file is missing in the OpenWrt.

If I can‘t using ausearch, where can I get the original audit log file in the OpenWrt? In fact, I wanted a more detailed parsing of the raw logs output by the dmesg command.

1 Like

Right, unless you use the setcon() function in your program (but with various limitations as mentioned in the link to man setcon(3))

You should reconsider whether you actually want or need audit on your device because that comes with overhead that might not be worth it. Unless you know that you need audit you probably should not use it.

When you do not have audit installed then SELinux will log to the kernel ring buffer. You can use the dmesg command to read and manage it. One of the nice aspects of this feature is that it is just memory and you can define how much memory it can use. The logd component also reads the kernel ring buffer I believe and so you can use that as well (for example you could use logread with all its features.

If you really need audit for some reason then, I suppose, you have to create those /etc/audit/auditd.conf and /var/log/audit/audit.log files yourself.

I recommend you not use audit.

See https://linux.die.net/man/8/auditd.conf

Looks like you can use the log_file option in that file to tell auditd where to store the logs.

See https://linux.die.net/man/8/ausearch

Looks like you can use the --input-logs option to tell ausearch to look for logs using the location specified with log_file in /etc/audit/auditd.conf.

Thanks for your great advice.

I will have a try!