Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.
RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.

Bug 888502

Summary: libvirt doesn't label console, serial sockets
Product: Red Hat Enterprise Linux 7 Reporter: Richard W.M. Jones <rjones>
Component: selinux-policyAssignee: Miroslav Grepl <mgrepl>
Status: CLOSED CURRENTRELEASE QA Contact: BaseOS QE Security Team <qe-baseos-security>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.0CC: acathrow, berrange, dwalsh, jdenemar, leiwang, mbooth, misc, mmalik, pmoore
Target Milestone: rcKeywords: Reopened
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 853393 Environment:
Last Closed: 2013-07-30 21:00:34 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 853393    
Bug Blocks: 857453    

Description Richard W.M. Jones 2012-12-18 19:31:17 UTC
Somehow this bug is not fixed in RHEL 7, even though I
am using the package:

selinux-policy-3.11.1-63.el7.noarch

and libguestfs is labelling the socket.  Would there be
a reason why svirt_socket_t would not work in RHEL 7?

+++ This bug was initially created as a clone of Bug #853393 +++

Description of problem:

In libguestfs with the libvirt backend we create sockets
to talk to the daemon and console like this:

    <serial type="unix">
      <source mode="connect" path="/tmp/libguestfs3vK8dN/console.sock"/>
      <target port="0"/>
    </serial>
    <channel type="unix">
      <source mode="connect" path="/tmp/libguestfs3vK8dN/guestfsd.sock"/>
      <target type="virtio" name="org.libguestfs.channel.0"/>
    </channel>

where "/tmp/libguestfs3vK8dN" is a temporary directory created
by libguestfs.

Note that these socket files are created by libguestfs.  Qemu has
to connect to them.

libvirt labels most things -- disks, kernel etc -- but it doesn't
label the console socket (and possibly not the virtio socket either,
but see below).  Therefore when SELinux is Enforcing, qemu
cannot connect to the console socket.

If SELinux is Permissive then we get the following AVC:

type=AVC msg=audit(1346412361.391:3414): avc:  denied  { connectto } for  pid=24102 comm="qemu-kvm" path="/tmp/libguestfs3vK8dN/console.sock" scontext=unconfined_u:unconfined_r:svirt_t:s0:c471,c928 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket

[...]

--- Additional comment from Daniel Walsh on 2012-12-07 12:38:37 EST ---

One potential fix for this would be create a new type guestfs_socket_t for the socket and then allow svirt_t to connect to it.

guestfs could do something like the following pseudo code.

getcon(&scon)
con=context_new(scon)
context_set_type(con,"guestfs_socket_t")
setsockcreatecon(context_str(con))
sock = socket()
context_free(con)
freecon(scon)

# cat mypol.te
policy_module(mypol,1.0)
gen_require(`
type svirt_t;
role unconfined_r;
')
type guestfs_socket_t;
role unconfined_r types guestfs_socket_t;

allow svirt_t guestfs_socket_t:unix_stream_socket connectto;

# make -f /usr/share/selinux/devel/Makefile
# semodule -i mypol.pp

--- Additional comment from Daniel Walsh on 2012-12-07 12:39:17 EST ---

Of course we would have to formalize how guestfs gets the name of its socket, if this works...

--- Additional comment from Richard W.M. Jones on 2012-12-11 06:03:44 EST ---

(In reply to comment #16)
> One potential fix for this would be create a new type guestfs_socket_t for
> the socket and then allow svirt_t to connect to it.
> 
> guestfs could do something like the following pseudo code.
> 
> getcon(&scon)
> con=context_new(scon)
> context_set_type(con,"guestfs_socket_t")
> setsockcreatecon(context_str(con))
> sock = socket()
> context_free(con)
> freecon(scon)
> 
> # cat mypol.te
> policy_module(mypol,1.0)
> gen_require(`
> type svirt_t;
> role unconfined_r;
> ')
> type guestfs_socket_t;
> role unconfined_r types guestfs_socket_t;
> 
> allow svirt_t guestfs_socket_t:unix_stream_socket connectto;
> 
> # make -f /usr/share/selinux/devel/Makefile
> # semodule -i mypol.pp

I added all of this to libguestfs.  The setsockcreatecon
call is fine, but the subsequent socket call fails with -EPERM:

libguestfs: error: socket: Permission denied

and this AVC:

type=SYSCALL msg=audit(11/12/12 10:43:55.237:2060) : arch=x86_64 syscall=socket success=no exit=-13(Permission denied) a0=local a1=SOCK_STREAM|SOCK_CLOEXEC a2=ip a3=0x7fff6702d380 items=0 ppid=26899 pid=26957 auid=rjones uid=rjones gid=rjones euid=rjones suid=rjones fsuid=rjones egid=rjones sgid=rjones fsgid=rjones tty=pts3 ses=2 comm=lt-libguestfs-t exe=/home/rjones/d/libguestfs/test-tool/.libs/lt-libguestfs-test-tool subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) 
type=AVC msg=audit(11/12/12 10:43:55.237:2060) : avc:  denied  { create } for  pid=26957 comm=lt-libguestfs-t scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:guestfs_socket_t:s0-s0:c0.c1023 tclass=unix_stream_socket 

To cut a long story short, I updated the policy until I finally
got everything working.  Here is my updated policy:

---------------------------------------------
policy_module(mypol,1.0)
gen_require(`
type svirt_t;
type unconfined_t;
type svirt_image_t;
role unconfined_r;
')
type guestfs_socket_t;
role unconfined_r types guestfs_socket_t;

allow svirt_t guestfs_socket_t:unix_stream_socket connectto;

# necessary, but why??? - maybe a bug in libvirt labelling code?
allow svirt_t svirt_image_t:sock_file write;

allow unconfined_t guestfs_socket_t:unix_stream_socket { create bind listen accept write read };
---------------------------------------------

(In reply to comment #17)
> Of course we would have to formalize how guestfs gets the name of its
> socket, if this works...

Why can't we just create sockets in our tmpdir and label them?  I'm quite
happy to add this setsockcreatecon call to libguestfs, and continuing
to use /tmp means (a) we don't have to make invasive changes to the
code to create a third temporary location, (b) we don't have to worry
about naming issues, and (c) the sockets will get cleaned up automatically
(if we fail to) by the tmp cleaner.  This seems a much better solution
all round.

--- Additional comment from Richard W.M. Jones on 2012-12-11 06:04:47 EST ---

Created attachment 661371 [details]
0001-launch-libvirt-Label-sockets-with-guestfs_socket_t-R.patch

Proposed labelling patch for libguestfs.

--- Additional comment from Daniel Walsh on 2012-12-11 14:42:10 EST ---

I changed to use svirt_socket_t rather then guestfs_socket_t so this solution could be generalized.  selinux-policy-3.11.1-63.fc18 will include this policy.

Way back when we created svirt we created virtual_domain_context without using named value pairs.

cat /etc/selinux/targeted/contexts/virtual_domain_context 
system_u:system_r:svirt_t:s0

for lxc we have fixed this.

cat /etc/selinux/targeted/contexts/lxc_contexts 
process = "system_u:system_r:svirt_lxc_net_t:s0"
file = "system_u:object_r:svirt_lxc_file_t:s0"
content = "system_u:object_r:virt_var_lib_t:s0"


So currently we have no good way of allowing the polciy writer to establish the svirt_socket_t so that libguest could discover it. I am not thrilled with hard coding it, although it will probably always be there.

[...]