Bug 2276917

Summary: SELinux denial for /etc/libvirt/hooks/network
Product: [Fedora] Fedora Reporter: Jonathan Billings <jbilling>
Component: selinux-policyAssignee: Zdenek Pytela <zpytela>
Status: CLOSED ERRATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: medium    
Version: 40CC: agurenko, aperotti, arusakov, berrange, cfergeau, clalancette, crobinso, dwalsh, ivanov17, jbreitwe, jforbes, jiyin, jortialc, knazekovan, laine, lcheng, libvirt-maint, lvrabec, mbukatov, mhofmann, mmalik, mteixeira, omosnacek, pkoncity, pstourac, sgraf, smalloy, virt-maint, vmojzis, zpytela
Target Milestone: ---Keywords: Upgrades
Target Release: ---Flags: jbilling: needinfo-
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: selinux-policy-40.24-1.fc40 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2024-07-19 01:46:02 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Jonathan Billings 2024-04-24 15:50:36 UTC
Hello,

After the upgrade from Fedora 39 to Fedora 40, I'm getting SELinux denials when trying to start the default libvirtd network.  When I looked into it, the errors were:

Error starting network 'default': Hook script execution failed: internal error: Child process (LC_ALL=C PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin USER=root /etc/libvirt/hooks/network default start begin -) unexpected exit status 126: libvirt:  error : cannot execute binary /etc/libvirt/hooks/network: Permission denied


Traceback (most recent call last):
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 72, in cb_wrapper
    callback(asyncjob, *args, **kwargs)
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 108, in tmpcb
    callback(*args, **kwargs)
  File "/usr/share/virt-manager/virtManager/object/libvirtobject.py", line 57, in newfn
    ret = fn(self, *args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/virt-manager/virtManager/object/network.py", line 69, in start
    self._backend.create()
  File "/usr/lib64/python3.12/site-packages/libvirt.py", line 3553, in create
    raise libvirtError('virNetworkCreate() failed')
libvirt.libvirtError: Hook script execution failed: internal error: Child process (LC_ALL=C PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin USER=root /etc/libvirt/hooks/network default start begin -) unexpected exit status 126: libvirt:  error : cannot execute binary /etc/libvirt/hooks/network: Permission denied

The default network comes online when it's in Permissive mode.  I'm filing this against libvirt but it might require an selinux policy update instead, I'm not sure.  

I collected the audit logs for when I enable and disable the default network:

time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.628:2316): avc:  denied  { execute } for  pid=76278 comm="rpc-virtnetwork" name="network" dev="dm-0" ino=249174 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:virt_etc_rw_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.628:2317): avc:  denied  { execute_no_trans } for  pid=76278 comm="rpc-virtnetwork" path="/etc/libvirt/hooks/network" dev="dm-0" ino=249174 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:virt_etc_rw_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.629:2318): avc:  denied  { execute } for  pid=76278 comm="rpc-virtnetwork" name="bash" dev="dm-0" ino=42419819 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:shell_exec_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.630:2319): avc:  denied  { map } for  pid=76278 comm="network" path="/usr/bin/bash" dev="dm-0" ino=42419819 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:shell_exec_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.813:2339): avc:  denied  { execute } for  pid=76313 comm="rpc-virtnetwork" name="network" dev="dm-0" ino=249174 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:virt_etc_rw_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.813:2340): avc:  denied  { execute_no_trans } for  pid=76313 comm="rpc-virtnetwork" path="/etc/libvirt/hooks/network" dev="dm-0" ino=249174 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:virt_etc_rw_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.813:2341): avc:  denied  { execute } for  pid=76313 comm="rpc-virtnetwork" name="bash" dev="dm-0" ino=42419819 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:shell_exec_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.814:2342): avc:  denied  { map } for  pid=76313 comm="network" path="/usr/bin/bash" dev="dm-0" ino=42419819 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:shell_exec_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.816:2343): avc:  denied  { execute } for  pid=76313 comm="network" name="resolvectl" dev="dm-0" ino=42505695 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.817:2344): avc:  denied  { execute_no_trans } for  pid=76314 comm="network" path="/usr/bin/resolvectl" dev="dm-0" ino=42505695 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:35 2024
type=AVC msg=audit(1713972755.817:2345): avc:  denied  { map } for  pid=76314 comm="resolvectl" path="/usr/bin/resolvectl" dev="dm-0" ino=42505695 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:bin_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:37 2024
type=AVC msg=audit(1713972757.829:2366): avc:  denied  { execute } for  pid=76371 comm="rpc-virtnetwork" name="network" dev="dm-0" ino=249174 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:virt_etc_rw_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:37 2024
type=AVC msg=audit(1713972757.829:2367): avc:  denied  { execute_no_trans } for  pid=76371 comm="rpc-virtnetwork" path="/etc/libvirt/hooks/network" dev="dm-0" ino=249174 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:virt_etc_rw_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:37 2024
type=AVC msg=audit(1713972757.829:2368): avc:  denied  { execute } for  pid=76371 comm="rpc-virtnetwork" name="bash" dev="dm-0" ino=42419819 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:shell_exec_t:s0 tclass=file permissive=1
----
time->Wed Apr 24 11:32:37 2024
type=AVC msg=audit(1713972757.830:2369): avc:  denied  { map } for  pid=76371 comm="network" path="/usr/bin/bash" dev="dm-0" ino=42419819 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:shell_exec_t:s0 tclass=file permissive=1


Converting those failures to a selinux policy module, it looks like:

# ausearch -m avc -ts recent | audit2allow -m libvirt_network

module libvirt_network 1.0;

require {
	type virtnetworkd_t;
	type virt_etc_rw_t;
	type bin_t;
	type shell_exec_t;
	class file { execute execute_no_trans map };
}

#============= virtnetworkd_t ==============
allow virtnetworkd_t bin_t:file { execute execute_no_trans };

#!!!! This avc can be allowed using the boolean 'domain_can_mmap_files'
allow virtnetworkd_t bin_t:file map;
allow virtnetworkd_t shell_exec_t:file execute;

#!!!! This avc can be allowed using the boolean 'domain_can_mmap_files'
allow virtnetworkd_t shell_exec_t:file map;
allow virtnetworkd_t virt_etc_rw_t:file { execute execute_no_trans };


Reproducible: Always

Steps to Reproduce:
1. Install libvirt-daemon, libvirt-client on Fedora 40
2. Create /etc/libvirt/hooks/ directory, put a shell script in that directory (it can just run /bin/true, the error is running it)
3. Try to bring up the default network: "virsh net-start default"
Actual Results:  
# virsh net-start default
error: Failed to start network default
error: Hook script execution failed: internal error: Child process (LC_ALL=C PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin USER=root /etc/libvirt/hooks/network default start begin -) unexpected exit status 126: libvirt:  error : cannot execute binary /etc/libvirt/hooks/network: Permission denied

Expected Results:  
# virsh net-start default
Network default started


$ rpm -q libvirt-daemon
libvirt-daemon-10.1.0-1.fc40.x86_64

$ rpm -q selinux-policy-targeted 
selinux-policy-targeted-40.16-1.fc40.noarch

$ matchpathcon /etc/libvirt/hooks/network
/etc/libvirt/hooks/network	system_u:object_r:virt_etc_rw_t:s0


I've performed a 'restorecon -rv /etc', which didn't solve anything.

Comment 1 Jonathan Billings 2024-04-24 15:51:35 UTC
I forgot to mention, /etc/libvirt/hooks/network isn't part of the package, but it is a supported configuration described in https://www.libvirt.org/hooks.html

Comment 2 Jonathan Billings 2024-04-30 12:39:23 UTC
Is this is something that can be resolved by libvirt maintainers, or do we need to have this moved to the selinux-policy package maintainers?

Comment 3 Daniel Berrangé 2024-04-30 14:13:45 UTC
Re-assigning since selinux-policy has had major changes in this release, so likely a regression there. Nothing on the libvirt side changed how we invoke hooks

Comment 8 ivanov17 2024-05-22 23:42:57 UTC
I have the same issue on Fedora 40:


# virsh net-start internal
error: Failed to start network internal
error: Hook script execution failed: internal error: Child process (LC_ALL=C PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin USER=root /etc/libvirt/hooks/network.d/00-nat.sh internal start begin -) unexpected exit status 126: libvirt:  error : cannot execute binary /etc/libvirt/hooks/network.d/00-nat.sh: Permission denied


# ls -lZ /etc/libvirt/hooks/network.d/00-nat.sh 
-rwx------. 1 root root system_u:object_r:virt_etc_rw_t:s0 490 Apr 24  2023 /etc/libvirt/hooks/network.d/00-nat.sh


# sealert -a /var/log/audit/audit.log
100% done
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------------------------------

SELinux is preventing daemon-init from execute access on the file /etc/libvirt/hooks/network.d/00-nat.sh.

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that daemon-init should be allowed execute access on the 00-nat.sh file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'daemon-init' --raw | audit2allow -M my-daemoninit
# semodule -X 300 -i my-daemoninit.pp


Additional Information:
Source Context                system_u:system_r:virtnetworkd_t:s0
Target Context                system_u:object_r:virt_etc_rw_t:s0
Target Objects                /etc/libvirt/hooks/network.d/00-nat.sh [ file ]
Source                        daemon-init
Source Path                   daemon-init
Port                          <Unknown>
Host                          <Unknown>
Source RPM Packages           
Target RPM Packages           
SELinux Policy RPM            selinux-policy-targeted-40.20-1.fc40.noarch
Local Policy RPM              selinux-policy-targeted-40.20-1.fc40.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     fedora
Platform                      Linux fedora 6.8.9-300.fc40.x86_64 #1 SMP
                              PREEMPT_DYNAMIC Thu May  2 18:59:06 UTC 2024
                              x86_64
Alert Count                   6
First Seen                    2024-05-23 02:04:42 +04
Last Seen                     2024-05-23 03:17:38 +04
Local ID                      b3eaa6ff-0f72-4033-8cfe-6a75e0b8290b

Raw Audit Messages
type=AVC msg=audit(1716419858.517:600): avc:  denied  { execute } for  pid=44939 comm="rpc-virtnetwork" name="00-nat.sh" dev="dm-1" ino=67775802 scontext=system_u:system_r:virtnetworkd_t:s0 tcontext=system_u:object_r:virt_etc_rw_t:s0 tclass=file permissive=0


Hash: daemon-init,virtnetworkd_t,virt_etc_rw_t,file,execute


# virsh version
Compiled against library: libvirt 10.1.0
Using library: libvirt 10.1.0
Using API: QEMU 10.1.0
Running hypervisor: QEMU 8.2.2

Comment 11 Zdenek Pytela 2024-06-12 08:28:07 UTC
*** Bug 2279956 has been marked as a duplicate of this bug. ***

Comment 12 Zdenek Pytela 2024-06-26 14:23:53 UTC
Unfortunately, I was unable to reproduce the original issue, I guess something more than in this bz and in https://issues.redhat.com/browse/RHEL-41168 is needed to set up.

However, I created a policy draft [1]. Can you test the coprbuild [2] in rawhide if this is sufficient?
Note relabeling is needed and the virt_hooks_unconfined boolean needs to be turned on:

restorecon -Rv /etc/libvirt/hooks
setsebool virt_hooks_unconfined on

[1] https://github.com/fedora-selinux/selinux-policy/pull/2195
[2] https://dashboard.packit.dev/results/copr-builds/1679959

Comment 16 Fedora Update System 2024-07-17 16:15:24 UTC
FEDORA-2024-f30b2bffdc (selinux-policy-40.24-1.fc40) has been submitted as an update to Fedora 40.
https://bodhi.fedoraproject.org/updates/FEDORA-2024-f30b2bffdc

Comment 17 Fedora Update System 2024-07-18 04:59:09 UTC
FEDORA-2024-f30b2bffdc has been pushed to the Fedora 40 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2024-f30b2bffdc`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2024-f30b2bffdc

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 18 Fedora Update System 2024-07-19 01:46:02 UTC
FEDORA-2024-f30b2bffdc (selinux-policy-40.24-1.fc40) has been pushed to the Fedora 40 stable repository.
If problem still persists, please make note of it in this bug report.