Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.
Bug 1958210 - selinux-policy is blocking alsa-state.service from executing modprobe and from writing to sysfs
Summary: selinux-policy is blocking alsa-state.service from executing modprobe and fro...
Keywords:
Status: NEW
Alias: None
Product: Fedora
Classification: Fedora
Component: selinux-policy
Version: rawhide
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: ---
Assignee: Zdenek Pytela
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2021-05-07 13:00 UTC by Hans de Goede
Modified: 2021-05-23 15:08 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed:
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Hans de Goede 2021-05-07 13:00:33 UTC
Kernel 5.13 will have support to bind certain alsa mixer controls to LED triggers from userspace (to control the mute-LEDS found on some devices (typically embedded inside the keyboard's mute keys).

The idea behind this is that this way this, often device specific, policy info can be stored in userspace in ALSA UCM profile config files, in the same way how many device specific mixer configurations are also stored in userspace in UCM profiles.

I've been working on adding support for the mute LEDs on some devices using this new kernel capability, this involves adding a config snippet like this to the UCM profile for the device:

FixedBootSequence [
       exec "/sbin/modprobe snd_ctl_led"
       sysw "-/class/sound/ctl-led/speaker/card${CardNumber}/attach:DAC1 Playback Switch"
       sysw "-/class/sound/ctl-led/mic/card${CardNumber}/attach:ADC Capture Switch"
]

As you can see this does 2 things, it calls modprobe to load the kernel module implementing the new functionality and then it does 2 writes to files under sysfs.

In order for this to work properly I had to put selinux in permissive mode. While running in permissive mode the following AVCs related to this were generated:

type=AVC msg=audit(1620391593.920:122): avc:  denied  { execute } for  pid=549 comm="sh" name="kmod" dev="mmcblk1p4" ino=536329 scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:object_r:kmod_exec_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.920:123): avc:  denied  { read open } for  pid=549 comm="sh" path="/usr/bin/kmod" dev="mmcblk1p4" ino=536329 scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:object_r:kmod_exec_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.920:124): avc:  denied  { execute_no_trans } for  pid=549 comm="sh" path="/usr/bin/kmod" dev="mmcblk1p4" ino=536329 scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:object_r:kmod_exec_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.936:125): avc:  denied  { map } for  pid=549 comm="modprobe" path="/usr/bin/kmod" dev="mmcblk1p4" ino=536329 scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:object_r:kmod_exec_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.957:126): avc:  denied  { read } for  pid=549 comm="modprobe" name="modprobe.d" dev="mmcblk1p4" ino=1175142 scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:object_r:modules_conf_t:s0 tclass=dir permissive=1
type=AVC msg=audit(1620391593.957:127): avc:  denied  { getattr } for  pid=549 comm="modprobe" path="/etc/modprobe.d/mlx4.conf" dev="mmcblk1p4" ino=1176808 scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:object_r:modules_conf_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.968:128): avc:  denied  { read } for  pid=549 comm="modprobe" name="kvm.conf" dev="mmcblk1p4" ino=1176803 scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:object_r:modules_conf_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.968:129): avc:  denied  { open } for  pid=549 comm="modprobe" path="/etc/modprobe.d/kvm.conf" dev="mmcblk1p4" ino=1176803 scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:object_r:modules_conf_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.969:130): avc:  denied  { read } for  pid=549 comm="modprobe" name="modules.softdep" dev="mmcblk1p4" ino=539755 scontext=system_u:system_r:alsa_t:s0 tcontext=unconfined_u:object_r:modules_object_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.969:131): avc:  denied  { open } for  pid=549 comm="modprobe" path="/usr/lib/modules/5.12.0+/modules.softdep" dev="mmcblk1p4" ino=539755 scontext=system_u:system_r:alsa_t:s0 tcontext=unconfined_u:object_r:modules_object_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.969:132): avc:  denied  { getattr } for  pid=549 comm="modprobe" path="/usr/lib/modules/5.12.0+/modules.softdep" dev="mmcblk1p4" ino=539755 scontext=system_u:system_r:alsa_t:s0 tcontext=unconfined_u:object_r:modules_object_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.969:133): avc:  denied  { map } for  pid=549 comm="modprobe" path="/usr/lib/modules/5.12.0+/modules.dep.bin" dev="mmcblk1p4" ino=539760 scontext=system_u:system_r:alsa_t:s0 tcontext=unconfined_u:object_r:modules_object_t:s0 tclass=file permissive=1
type=AVC msg=audit(1620391593.985:134): avc:  denied  { module_load } for  pid=549 comm="modprobe" scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:system_r:alsa_t:s0 tclass=system permissive=1
type=AVC msg=audit(1620391594.022:135): avc:  denied  { write } for  pid=541 comm="alsactl" name="attach" dev="sysfs" ino=32883 scontext=system_u:system_r:alsa_t:s0 tcontext=system_u:object_r:sysfs_t:s0 tclass=file permissive=1

It seems to me that this can be simplified into 2 problems (but I'm not a selinux expert):

1. The selinux policy for the alsa-state.service needs to be amended to allow executing modprobe; and allowing a transition to kmod_t on this execute which should fix all but one of the AVCs above

2. The selinux policy for the alsa-state.service needs to be amended to allow it to write to sysfs files.

If you can provide me with a selinux-module source for me to add with "semodule -i" to test, then I would be more then happy to test any suggested changes to make sure that they actually fix this.

Comment 1 Zdenek Pytela 2021-05-07 16:36:26 UTC
Hans,

Thank you for the detailed description. I think you are also correct with the solution.

# cat local_alsa_state.cil
(allow alsa_t kmod_exec_t (file (getattr open map read execute ioctl execute_no_trans)))
(allow alsa_t kmod_t (process (transition)))
(typetransition alsa_t kmod_exec_t process kmod_t)
(allow kmod_t alsa_t (fd (use)))
(allow kmod_t alsa_t (fifo_file (getattr read write append ioctl lock)))
(allow kmod_t alsa_t (process (sigchld)))
(allow alsa_t sysfs_t (file (getattr write)))
# semodule -i local_alsa_state.cil

Regarding sysfs: There is only need to write to existing files? The file descriptor is inherited so that just write permission is needed?
Once implemented, will there be a way to test the feature?
Will this kernel also get to F34 later?

If there are further denials, it would be helpful to enable full auditing:

1) Open the /etc/audit/rules.d/audit.rules file in an editor.
2) Remove the following line if it exists:
-a task,never
3) Add the following line to the end of the file:
-w /etc/shadow -p w
4) Restart the audit daemon:
  # service auditd restart
5) Re-run the scenario.
6) Collect AVC denials:
  # ausearch -i -m avc,user_avc,selinux_err,user_selinux_err -ts today

Comment 2 Ondrej Mosnacek 2021-05-07 16:50:46 UTC
(In reply to Zdenek Pytela from comment #1)
> Regarding sysfs: There is only need to write to existing files?

Sysfs files are usually created by the kernel, so that wouldn't be surprising.

> The file descriptor is inherited so that just write permission is needed?

$ sesearch -s alsa_t -t sysfs_t -A
allow alsa_t sysfs_t:dir { ioctl lock read };
allow alsa_t sysfs_t:file { getattr ioctl lock open read };
allow alsa_t sysfs_t:lnk_file { getattr read };
allow domain file_type:blk_file map; [ domain_can_mmap_files ]:True
allow domain file_type:chr_file map; [ domain_can_mmap_files ]:True
allow domain file_type:file map; [ domain_can_mmap_files ]:True
allow domain file_type:lnk_file map; [ domain_can_mmap_files ]:True
allow domain sysfs_t:dir { getattr open search };
allow domain sysfs_t:filesystem getattr;

So I think it needs also open/read/getattr, but these are already granted today.

> Will this kernel also get to F34 later?

I'd say it's very likely. F33 started with 5.8.x and now it's at 5.11.x. F34 is starting at 5.11.x, so it'll probably get up to 5.14 or 5.15 before going EOL.


Note You need to log in before you can comment on or make changes to this bug.