Bug 1782539

Summary: dnsmasq tftp is not able to read files with SELinux public_content_t context
Product: Red Hat Enterprise Linux 8 Reporter: Benjamin <benc>
Component: selinux-policyAssignee: Zdenek Pytela <zpytela>
Status: CLOSED ERRATA QA Contact: Milos Malik <mmalik>
Severity: low Docs Contact:
Priority: low    
Version: 8.1CC: lvrabec, mmalik, plautrba, ssekidde
Target Milestone: rcKeywords: Triaged
Target Release: 8.4   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: No Doc Update
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-05-18 14:57:35 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:

Description Benjamin 2019-12-11 19:52:03 UTC
Description of problem:
The tftp server of dnsmasq should be able to access files labeled with the public_content_t as the server from tftp-server is able to.

Version-Release number of selected component (if applicable):
dnsmasq-2.79-6.el8.x86_64

How reproducible:
always

Steps to Reproduce:
1. Create a dnsmasq configuration with the tftp service enabled

For example in /etc/dnsmasq.conf include:
enable-tftp
tftp-root=/tftpboot

2. Label the files in /tftpboot with the public_content_t so they can also be served with other services.

# semanage fcontext -a -t public_content_t "/tftpboot(/.*)?"
# restorecon -R -v /tftpboot

Actual results:
Attempting to fetch a file from a tftp client results in:
dnsmasq-tftp[1075]: cannot access /tftpboot/filename: Permission denied

Expected results:
dnsmasq-tftp[9526]: sent /tftpboot/filename to 1.2.3.4


Additional info:
The same issue also occurs with RHEL7 with dnsmasq-2.76-10.el7_7.1.x86_64

Comment 1 Petr Menšík 2020-03-18 15:20:32 UTC
tftp-server uses different directory  /var/lib/tftpboot

# ls -lZd /var/lib/tftpboot
drwxr-xr-x. root root system_u:object_r:tftpdir_rw_t:s0 /var/lib/tftpboot

dnsmasq does not have any dedicated directory for tftp. I think /var/lib/dnsmasq/<anything> could be used, but dnsmasq directory itself usually contains leases. Which must not be public.
Such directory is served in Fedora by syslinux-tftpboot, where it has type tftpdir_t.

Anyway, why is chosen public_content_t type? Since it was assigned manually, why is not used dnsmasq_lease_t?

Comment 2 Benjamin 2020-04-01 16:09:46 UTC
The files are in /tftpboot (this is a pxe boot server), they are served using dnsmasq's tftp service and through nginx over http. If I label them tftpdir_t, nginx cannot access them. Likewise if I label them httpd_sys_content_t, dnsmasq cannot access them.

Reading httpd_selinux(8) it mentions in the "SHARING FILES" section:
  If you want to share files with multiple domains (Apache, FTP, rsync, Samba), you can set a file context of public_content_t and public_content_rw_t.

That allows nginx to read the files but dnsmasq is still not able to. I opened this issue since the tftpd daemon in the tftpd-server package can read files labeled public_content_t. It seems if tftpd-server can read them, then dnsmasq tftp should be able to read them as well.

Comment 3 Petr Menšík 2020-04-07 09:23:24 UTC
Ok, you are right, it makes sense to set it to public_content_t, if it should be served also over HTTP. Especially if tftp-server already has such ability, dnsmasq should have it as well. It can provide the same service.

Comment 4 Petr Menšík 2020-04-07 09:31:15 UTC
Hello Selinux team,

I think dnsmasq cannot change allowed context.

Could be file context type dnsmasq_exec_t allowed to read public_content_t?

Comment 5 Milos Malik 2020-04-07 10:20:21 UTC
Caught in enforcing mode:
----
type=PROCTITLE msg=audit(04/07/2020 06:19:29.459:1283) : proctitle=/usr/sbin/dnsmasq -k 
type=PATH msg=audit(04/07/2020 06:19:29.459:1283) : item=0 name=/tftpboot/pokus inode=10620096 dev=fd:01 mode=file,644 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:public_content_t:s0 nametype=NORMAL cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0 
type=CWD msg=audit(04/07/2020 06:19:29.459:1283) : cwd=/ 
type=SYSCALL msg=audit(04/07/2020 06:19:29.459:1283) : arch=x86_64 syscall=openat success=no exit=EACCES(Permission denied) a0=0xffffff9c a1=0x56165c67f700 a2=O_RDONLY a3=0x0 items=1 ppid=1 pid=130280 auid=unset uid=dnsmasq gid=dnsmasq euid=dnsmasq suid=dnsmasq fsuid=dnsmasq egid=dnsmasq sgid=dnsmasq fsgid=dnsmasq tty=(none) ses=unset comm=dnsmasq exe=/usr/sbin/dnsmasq subj=system_u:system_r:dnsmasq_t:s0 key=(null) 
type=AVC msg=audit(04/07/2020 06:19:29.459:1283) : avc:  denied  { read } for  pid=130280 comm=dnsmasq name=pokus dev="vda1" ino=10620096 scontext=system_u:system_r:dnsmasq_t:s0 tcontext=system_u:object_r:public_content_t:s0 tclass=file permissive=0 
----

Comment 6 Milos Malik 2020-04-07 10:30:18 UTC
Caught in permissive mode:
----
type=PROCTITLE msg=audit(04/07/2020 06:28:21.429:1288) : proctitle=/usr/sbin/dnsmasq -k 
type=PATH msg=audit(04/07/2020 06:28:21.429:1288) : item=0 name=/tftpboot/pokus inode=10620096 dev=fd:01 mode=file,644 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:public_content_t:s0 nametype=NORMAL cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0 
type=CWD msg=audit(04/07/2020 06:28:21.429:1288) : cwd=/ 
type=SYSCALL msg=audit(04/07/2020 06:28:21.429:1288) : arch=x86_64 syscall=openat success=yes exit=17 a0=0xffffff9c a1=0x56165c67f700 a2=O_RDONLY a3=0x0 items=1 ppid=1 pid=130280 auid=unset uid=dnsmasq gid=dnsmasq euid=dnsmasq suid=dnsmasq fsuid=dnsmasq egid=dnsmasq sgid=dnsmasq fsgid=dnsmasq tty=(none) ses=unset comm=dnsmasq exe=/usr/sbin/dnsmasq subj=system_u:system_r:dnsmasq_t:s0 key=(null) 
type=AVC msg=audit(04/07/2020 06:28:21.429:1288) : avc:  denied  { open } for  pid=130280 comm=dnsmasq path=/tftpboot/pokus dev="vda1" ino=10620096 scontext=system_u:system_r:dnsmasq_t:s0 tcontext=system_u:object_r:public_content_t:s0 tclass=file permissive=1 
type=AVC msg=audit(04/07/2020 06:28:21.429:1288) : avc:  denied  { read } for  pid=130280 comm=dnsmasq name=pokus dev="vda1" ino=10620096 scontext=system_u:system_r:dnsmasq_t:s0 tcontext=system_u:object_r:public_content_t:s0 tclass=file permissive=1 
----
type=PROCTITLE msg=audit(04/07/2020 06:28:21.429:1289) : proctitle=/usr/sbin/dnsmasq -k 
type=SYSCALL msg=audit(04/07/2020 06:28:21.429:1289) : arch=x86_64 syscall=fstat success=yes exit=0 a0=0x11 a1=0x7ffe0f35c980 a2=0x7ffe0f35c980 a3=0x0 items=0 ppid=1 pid=130280 auid=unset uid=dnsmasq gid=dnsmasq euid=dnsmasq suid=dnsmasq fsuid=dnsmasq egid=dnsmasq sgid=dnsmasq fsgid=dnsmasq tty=(none) ses=unset comm=dnsmasq exe=/usr/sbin/dnsmasq subj=system_u:system_r:dnsmasq_t:s0 key=(null) 
type=AVC msg=audit(04/07/2020 06:28:21.429:1289) : avc:  denied  { getattr } for  pid=130280 comm=dnsmasq path=/tftpboot/pokus dev="vda1" ino=10620096 scontext=system_u:system_r:dnsmasq_t:s0 tcontext=system_u:object_r:public_content_t:s0 tclass=file permissive=1 
----

Comment 7 Milos Malik 2020-04-07 11:02:11 UTC
Simplified reproducer:

# yum -y -q install tftp dnsmasq
# mkdir -p /tftpboot
# touch /tftpboot/pokus
# semanage fcontext -a -t public_content_t "/tftpboot(/.*)?"
# restorecon -RvF /tftpboot
# grep tftp /etc/dnsmasq.conf | grep -v ^#
enable-tftp
tftp-root=/tftpboot
# service dnsmasq start
# tftp localhost -c get pokus
Error code 2: cannot access /tftpboot/pokus: Permission denied
#

Hopefully, I didn't forget some important step.

Comment 9 Zdenek Pytela 2020-04-07 12:23:11 UTC
Allowing the access seems to be one of the options.

Comment 13 Zdenek Pytela 2020-11-16 20:43:08 UTC
I've submitted a Fedora PR to address the issue:
https://github.com/fedora-selinux/selinux-policy-contrib/pull/367

Comment 21 errata-xmlrpc 2021-05-18 14:57:35 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (selinux-policy bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2021:1639