[PATCH] selinux-policy: update to version v2.0

Dominick Grift dominick.grift at defensec.nl
Mon Jan 13 23:27:43 PST 2025


Stefan Hellermann <stefan at the2masters.de> writes:

> Hi! Thank you for your really fast changes!

Thank you for your feedback. It is appreciated. Comments below:

>
> With your last commit f86def7e there are 3 new errors for /dev/urandom:
>
> [...]
> [    1.749370] init: - preinit -
> [    2.437887] audit: type=1400 audit(1736810585.360:3): avc: denied 
> { getattr } for  pid=886 comm="jshn" path="/dev/urandom" dev="tmpfs"
> ino=31 scontext=sys.id:sys.role:jshn.subj
> tcontext=sys.id:sys.role:random.nodedev tclass=chr_file permissive=1
> [    2.438371] audit: type=1400 audit(1736810585.360:4): avc: denied 
> { read } for  pid=886 comm="jshn" name="urandom" dev="tmpfs" ino=31
> scontext=sys.id:sys.role:jshn.subj
> tcontext=sys.id:sys.role:random.nodedev tclass=chr_file permissive=1
> [    2.439138] audit: type=1400 audit(1736810585.360:5): avc: denied 
> { open } for  pid=886 comm="jshn" path="/dev/urandom" dev="tmpfs"
> ino=31 scontext=sys.id:sys.role:jshn.subj
> tcontext=sys.id:sys.role:random.nodedev tclass=chr_file permissive=1
> [    4.994969] random: crng init done
> [...]

I will add this.

>
> And I cannot login on ttyAMA0:
>
> Please press Enter to activate this console.
>
> login: can't get SID for root

This is a bug in busybox-selinux. A fix for this was posted:
http://lists.busybox.net/pipermail/busybox/2022-July/089800.html but it
was never adopted. The aformentioned patch is tested and reviewed. It
address this bug.

Maybe OpenWrt can carry this patch or maybe someone with sway in the
busybox community can figure out why it was not committed and get it
in. I tried and failed. So unless something gets done this is going to
linger on forever.

>
>
> Login with ssh is ok. There is already a bug report for this, it's
> working fine without selinux:
> https://github.com/openwrt/openwrt/issues/17038

Here is the fix:
http://lists.busybox.net/pipermail/busybox/2022-July/089800.html

I just needs to be applied.

>
>
> After sysupgrade the "sysupgrade.tgz" error remains the same:
>
> [   12.155085] audit: type=1400 audit(1736811933.100:6): avc: denied 
> { associate } for  pid=1006 comm="mv" name="sysupgrade.tgz"
> scontext=sys.id:sys.role:dos.fs tcontext=sys.id:sys.role:xattr.fs
> tclass=filesystem permissive=1
>

This is not something I can fix in the policy. Whatever does this needs
to be asked not to and to use cp instead of mv. Fortunately this does
not happen in a stock system because it involves fat.

>
> And while doing sysupgrade from a local file in /tmp I get a bunch
> more (no luci here, just scp file to /tmp and start sysupgrade from
> ssh):

Its comlicated and theres quite a bit involved but let me touch on some
of it:

Youre using scp -O. This is legacy scp and it should be killed. If you
dont want to install the openssh-sftp-server package then use:

`cat openwrt-armsr-armv8-generic-squashfs-combined.img.gz | ssh
root at 192.168.1.1 "cat > /tmp/sysupgrade.img"`

dropbear uses /tmp to generate its hostkey and the way it does it is
selinux unfriendly. It means that if you use scp -O and you transfer a
file to /tmp that it ends up with the ssh hostkey label because usually
dropbear creates its hostkey in /tmp and then it moves it to
/etc/dropbear (again that stupid mv issue). Anyway I had to make do but
the gist is this: don't use scp -O. its dead and it needs to be burried.

I was expecting this and I documented it in the README and I will also
document it elsewhere. I will also think about this some more but I kind
of like this implementation so far. Anyway:

Youve scp'd the file as-is (with name
openwrt-armsr-armv8-generic-squashfs-combined.img.gz) and this caused
the file to be copied with a context that validate-firmware-image cannot
validate (read).

The solution is to either use LuCI (I worked on it yesterday) or to scp
the file with one of these names: firmware.bin sysupgrade.img
sysupgrade.bin. for example:

cat openwrt-ipq40xx-generic-linksys_mr8300-squashfs-sysupgrade.bin | ssh
root at openwrt "cat > /tmp/sysupgrade.bin"

I know its a bit fragile but I kind of like it and Luci and sysupgrade
https://... both do something like that so I figured that if i would
just clearly document this requirement it would be fine

https://git.defensec.nl/?p=selinux-policy.git;a=blob;f=src/file/tmpfile/sysupgradetmpfile.cil;h=325e12c7a4d014ca7ee1af6786d00b532846dac7;hb=HEAD

Long story short:
1. don't use scp -O
2. if you use openssh-sftp-server (scp without -O) then make sure that
you transfer the image as either firmware.bin, sysupgrade.bin or sysupgrade.img
3. if you just use plain `ssh` in a pipe (example) then you get full access so
that is the most flexible way to use ssh (and you dont need
openssh-sftp-server for it either).
4. you can also use sysupgrade online if you have a local webserver:

root at OpenWrt:~# getenforce && sysupgrade -v --test http://192.168.1.192/~kcinimod/stuff/openwrt-ipq40xx-generic-linksys_mr8300-squashfs-sysupgrade.bin
Enforcing
Downloading 'http://192.168.1.192/~kcinimod/stuff/openwrt-ipq40xx-generic-linksys_mr8300-squashfs-sysupgrade.bin'
Connecting to 192.168.1.192:80
Writing to '/tmp/sysupgrade.img'
/tmp/sysupgrade.img  100% |*******************************| 13111k  0:00:00 ETA
Download completed (13426016 bytes)
root at OpenWrt:~# echo $?
0

Yes, quite a bit to digest any I will consider supporting firmware
images with random names but eventually it is still fragile when people
try to use scp -O ...

>
> [   74.345700] audit: type=1400 audit(1736811834.460:6): avc: denied 
> { read write } for  pid=2854 comm="fwtool"
> name="openwrt-armsr-armv8-generic-squashfs-combined.img.gz"
> dev="tmpfs" ino=93 scontext=sys.id:sys.role:fwtool.subj
> tcontext=sys.id:sys.role:ssh.server.hostkey.file tclass=file
> permissive=1
> [   74.347589] audit: type=1400 audit(1736811834.460:7): avc: denied 
> { open } for  pid=2854 comm="fwtool"
> path="/tmp/openwrt-armsr-armv8-generic-squashfs-combined.img.gz"
> dev="tmpfs" ino=93 scontext=sys.id:sys.role:fwtool.subj
> tcontext=sys.id:sys.role:ssh.server.hostkey.file tclass=file
> permissive=1
> [   74.349106] audit: type=1400 audit(1736811834.460:8): avc: denied 
> { ioctl } for  pid=2854 comm="fwtool"
> path="/tmp/openwrt-armsr-armv8-generic-squashfs-combined.img.gz"
> dev="tmpfs" ino=93 ioctlcmd=0x5413
> scontext=sys.id:sys.role:fwtool.subj
> tcontext=sys.id:sys.role:ssh.server.hostkey.file tclass=file
> permissive=1
> [   74.770422] audit: type=1400 audit(1736811834.890:9): avc: denied 
> { read } for  pid=2864 comm="cat" name="cmdline" dev="proc"
> ino=4026531972 scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:cmdline.procfile tclass=file permissive=1
> [   74.771728] audit: type=1400 audit(1736811834.890:10): avc: denied 
> { open } for  pid=2864 comm="cat" path="/proc/cmdline" dev="proc"
> ino=4026531972 scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:cmdline.procfile tclass=file permissive=1
> [   74.800695] audit: type=1400 audit(1736811834.920:11): avc: denied 
> { read } for  pid=2865 comm="find" name="/" dev="tmpfs" ino=1
> scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:tmp.fs tclass=dir permissive=1
> [   74.801449] audit: type=1400 audit(1736811834.920:12): avc: denied 
> { open } for  pid=2865 comm="find" path="/dev" dev="tmpfs" ino=1
> scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:tmp.fs tclass=dir permissive=1
> [   74.807108] audit: type=1400 audit(1736811834.930:13): avc: denied 
> { getattr } for  pid=2865 comm="find" path="/dev/pts" dev="devpts"
> ino=1 scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:devpts.fs tclass=dir permissive=1
> [   74.807988] audit: type=1400 audit(1736811834.930:14): avc: denied 
> { read } for  pid=2865 comm="find" name="/" dev="devpts" ino=1
> scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:devpts.fs tclass=dir permissive=1
> [   74.808726] audit: type=1400 audit(1736811834.930:15): avc: denied 
> { open } for  pid=2865 comm="find" path="/dev/pts" dev="devpts" ino=1
> scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:devpts.fs tclass=dir permissive=1
> [   80.140951] kauditd_printk_skb: 35 callbacks suppressed
> [   80.140985] audit: type=1400 audit(1736811840.260:51): avc: denied 
> { remove_name } for  pid=3459 comm="rm" name="image.bs" dev="tmpfs"
> ino=96 scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:tmp.fs tclass=dir permissive=1
> [   80.141666] audit: type=1400 audit(1736811840.260:52): avc: denied 
> { unlink } for  pid=3459 comm="rm" name="image.bs" dev="tmpfs" ino=96
> scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:tmp.fs tclass=file permissive=1
> [   87.255570] audit: type=1400 audit(1736811847.370:53): avc: denied 
> { getattr } for  pid=3955 comm="find" path="/dev/hwrng" dev="tmpfs"
> ino=14 scontext=sys.id:sys.role:validatefirmwareimage.subj
> tcontext=sys.id:sys.role:hwrng.nodedev tclass=chr_file permissive=1

I will look into adding rules for some of these validate-firmware-image
related events. Not sure what is happening there with "image.bs" ...

Thanks

>
> This is all done on a fresh openwrt checkout, I added your selinux
> updates and build the image with this config:
>
> CONFIG_TARGET_armsr=y
> CONFIG_TARGET_armsr_armv8=y
> CONFIG_TARGET_armsr_armv8_DEVICE_generic=y
> CONFIG_PACKAGE_qemu-ga=y
> CONFIG_SELINUX=y
>
> I can send you the compressed image file, if you want to try it
> yourself with qemu/virt-manager.

No thanks. All the events you pasted above are either normal rough edges
or issues that I am aware of but that are only documented in my
policy/repository. Eventually I am going to write a wiki page that
summarizes all the "gotches".

Thanks!

>
> Regards,
> Stefan Hellermann
>
>
> Am 13.01.25 um 18:52 schrieb Dominick Grift:
>> Dominick Grift <dominick.grift at defensec.nl> writes:
>>
>>> Dominick Grift <dominick.grift at defensec.nl> writes:
>>>
>>>> Hi, Thank you for feedback. Comments inline below:
>>>>
>>>> Stefan Hellermann <stefan at the2masters.de> writes:
>>>>
>>> <snip>
>>>
>>>>> audit(1736704702.290:4): avc:  denied  { associate } for  pid=1010
>>>>> comm="mv" name="sysupgrade.tgz" scontext=sys.id:sys.role:dos.fs
>>>>> tcontext=sys.id:sys.role:xattr.fs tclass=filesystem permissive=1
>>>> This is caused by mv'ing the file from a fat filesystem (fat does not
>>>> support extended attributes) to an extended attribute file system. When
>>>> you mv a file you also mv its associated context with it.
>>>>
>>>> This should not be allowed. Instead you should use cp. mv does not make
>>>> much sense anyway cross filesystem.
>>>>
>>> This bothered me so I would like to explain why I object to this.
>>>
>>> mv and cp are more complicated than some think. I see this all the time
>>> where people for example use `cp -a` without realizing the consequences.
>>>
>>> But regardless of this, coreutils has extensive support for SELinux and
>>> `mv -Z` would have addressed the above challenge. The issue is that
>>> busybox' `mv` does not support -Z and so eventually I will have to draw
>>> the line somewhere anyway. This seems like a good place to start.
>>>
>>>>> Sun Jan 12 17:58:25 2025 user.warn kernel: urandom-seed: Seed file not
>>>>> found (/etc/urandom.seed)
>>>>> Sun Jan 12 17:58:25 2025 user.info kernel: procd: - early -
>>>>> Sun Jan 12 17:58:25 2025 kern.notice kernel: audit: type=1400
>>>>> audit(1736704702.590:5): avc:  denied  { write } for  pid=1166
>>>>> comm="mkdir" name="/" dev="tmpfs" ino=1
>>>>> scontext=sys.id:sys.role:hotplug.call.subj
>>>>> tcontext=sys.id:sys.role:tmp.fs tclass=dir permissive=1
>>>>> Sun Jan 12 17:58:25 2025 kern.notice kernel: audit: type=1400
>>>>> audit(1736704702.590:6): avc:  denied  { add_name } for  pid=1166
>>>>> comm="mkdir" name="virtio-ports"
>>>>> scontext=sys.id:sys.role:hotplug.call.subj
>>>>> tcontext=sys.id:sys.role:tmp.fs tclass=dir permissive=1
>>>>> Sun Jan 12 17:58:25 2025 kern.notice kernel: audit: type=1400
>>>>> audit(1736704702.590:7): avc:  denied  { create } for  pid=1166
>>>>> comm="mkdir" name="virtio-ports"
>>>>> scontext=sys.id:sys.role:hotplug.call.subj
>>>>> tcontext=sys.id:sys.role:tmp.fs tclass=dir permissive=1
>>>>> Sun Jan 12 17:58:25 2025 kern.notice kernel: audit: type=1400
>>>>> audit(1736704702.590:8): avc:  denied  { create } for  pid=1167
>>>>> comm="ln" name="org.qemu.guest_agent.0"
>>>>> scontext=sys.id:sys.role:hotplug.call.subj
>>>>> tcontext=sys.id:sys.role:tmp.fs tclass=lnk_file permissive=1
>>>>> Sun Jan 12 17:58:25 2025 user.info kernel: procd: - ubus -
>>>>> Sun Jan 12 17:58:25 2025 user.info kernel: procd: - init -
>> I added support for this. We'll see where this leads. I might end up
>> reverting it later.
>>
>> https://git.defensec.nl/?p=selinux-policy.git;a=commitdiff;h=32c0cc897f679b6d2b204bc2935d9de3b7006944
>>
>>>> This seems like an 'exotic hotplug script'. I have an accomodation for
>>>> this. see if this comment helps:
>>>> https://git.defensec.nl/?p=selinux-policy.git;a=blob;f=src/agent/sysagent/hotplugsysagent.cil;h=3987b8540ae537d174a74cceb2c89ce26ef3c813;hb=HEAD#l115
>>> We'll have to see how this will work out practically. I am open to
>>> suggestions for alternative approaches but this seems like a fair
>>> approach.
>>>
>>> There are also challenges here. For example in the above event, the
>>> script is trying to create a dir and symlink in /dev. In OpenWrt there
>>> is no (easy) way to make a distinction between devtmpfs and and a common
>>> tmpfs. If I we're to allow this then that would later potentially
>>> present challenges when another script wants to create a dir or symlink in /tmp.
>>>
>>> Again, eventually I would have to draw the line somewhere as to what
>>> should be allowed by default and what is to be considered exotic. This
>>> looks like a good place.
>>>
>>> Just trying to explain some of the rationale because I am open to better
>>> alternatives. I just don't see any.
>

-- 
gpg --locate-keys dominick.grift at defensec.nl (wkd)
Key fingerprint = FCD2 3660 5D6B 9D27 7FC6  E0FF DA7E 521F 10F6 4098
Dominick Grift
Mastodon: @kcinimod at defensec.nl



More information about the openwrt-devel mailing list