Bug 1527522

Summary: Logrotate is not allowed to send kill signal
Product: Red Hat Enterprise Linux 7 Reporter: Lukas Zapletal <lzap>
Component: selinux-policyAssignee: Lukas Vrabec <lvrabec>
Status: CLOSED ERRATA QA Contact: Milos Malik <mmalik>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.3CC: baptiste.agasse, lef, lvrabec, mgrepl, mmalik, plautrba, radoslaw.piliszek, ssekidde
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: selinux-policy-3.13.1-197.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-10-30 10:02:20 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 Lukas Zapletal 2017-12-19 12:29:15 UTC
Hello,

our daemon does not support systemctl reload because it simply cannot reload configuration files. Therefore we do not have this reload action implemented.

But we want to have ability to send SIGUSR1, SIGUSR2 or SIGHUP signals from our logrotate script. We have the following:

/bin/systemctl kill --signal=SIGUSR1 foreman-proxy

This gives us denial on RHEL 7.3:

type=USER_AVC msg=audit(1491468305.905:16288): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='avc:  denied  { stop } for auid=0 uid=0 gid=0 path="/usr/lib/systemd/system/foreman-proxy.service" cmdline="/bin/systemctl kill --signal=SIGUSR1 foreman-proxy" scontext=system_u:system_r:logrotate_t:s0-s0:c0.c1023 tcontext=system_u:object_r:systemd_unit_file_t:s0 tclass=service  exe="/usr/lib/systemd/systemd" sauid=0 hostname=? addr=? ter

We tried to use /usr/sbin/kill instead of systemctl without any luck. Please allow this in RHEL base policy, thanks.

Comment 2 Radosław Piliszek 2017-12-27 09:32:10 UTC
I believe this is a too broad change. It would be better to introduce a new type for foreman-proxy service.

Comment 3 Lukas Zapletal 2018-01-01 11:21:47 UTC
Indeed this opens doors to denial attacks. The proper way of fixing this is to make a patch into systemd so kill signal is no longer recognized as start/stop hook.

Alternatively, you can introduce a boolean flag that can be turned off by default (opt-in only) so we can turn this on in our deployment but users are still locked down.

Comment 4 Lukas Vrabec 2018-01-02 12:40:42 UTC
We can do boolean for this. It makes sense to me.

Comment 5 Radosław Piliszek 2018-01-04 07:45:38 UTC
I believe a boolean would give a false sense of higher security. I did some policy mining and found that:

There is already a rule:

allow logrotate_t domain : process signal ;

which essentially allows logrotate to send signals other than SIGKILL, SIGSTOP or SIGCHLD to virtually any other process (since all domain types should have domain attribute). So, well, adding systemd stopping would not be that bad (in fact only adding SIGKILL, SIGSTOP and SIGCHLD signals for systemd-managed services). :-)

In other words - logrotate scripts are already highly privileged with root user and wide permissions from SELinux.

Comment 6 Benjamin Lefoul 2018-02-28 19:46:52 UTC
(In reply to Lukas Vrabec from comment #4)
> We can do boolean for this. It makes sense to me.

Lukas, I also think some additional boolean tuning for logrotate would be very welcome in the policy.

I, too, am experiencing SELinux denials because of the relationship between cron and logrotate. In my case, crond_t transitions to system_cronjob_t by executing the following bin_t file:

~] ll -Z /etc/cron.daily/logrotate 
-rwx------. root root system_u:object_r:bin_t:s0       /etc/cron.daily/logrotate

See:
   allow system_cronjob_t bin_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ; 
   allow crond_t system_cronjob_t : process transition ; 
   allow crond_t bin_t : file { ioctl read getattr lock execute execute_no_trans open } ; 

However, /etc/cron.daily/logrotate does call explicitely "/usr/sbin/logrotate /etc/logrotate.conf", the only logrotate_exec_t on my system btw:

~] find / -context "*logrotate_exec_t*"
/usr/sbin/logrotate

Both crond_t and system_cronjob_t can execute that:
   allow system_cronjob_t logrotate_exec_t : file { read getattr execute open } ; 
   allow crond_t logrotate_exec_t : file { read getattr execute open } ; 

...to transition into logrotate_t:
   allow logrotate_t logrotate_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ; 
   allow system_cronjob_t logrotate_t : process transition ; 
   allow crond_t logrotate_t : process transition ; 

/etc/logrotate.conf in turn includes config found in /etc/logrotate.d, among which a file with a "postrotate" instruction calling another script in my system, which in turn had to execute something with "execstack" (I know, that's bad, but I have no control over this).

Ah, but that is one thing logrotate_t cannot do when system_cronjob_t (and crond_t) can, look:

~] sesearch -s crond_t -AC | grep execstack
ET allow crond_t crond_t : process execstack ; [ selinuxuser_execstack ]
~] sesearch -s system_cronjob_t -AC | grep execstack
ET allow system_cronjob_t system_cronjob_t : process execstack ; [ selinuxuser_execstack ]
~] sesearch -s logrotate_t -AC | grep execstack
~]


So a solution for me was to edit /etc/cron.daily/logrotate and use runcon by replacing:
"/usr/sbin/logrotate /etc/logrotate.conf" with:
"runcon -t system_cronjob_t /usr/sbin/logrotate /etc/logrotate.conf"

Obviously I don't like having to use runcon in an executable in my centralized config management tool.

It would have been nice to have a boolean such as cron_logrotate_transition_disabled to prevent system_cronjob_t and crond_t to transition to logrotate_t (execute_no_trans?). Combined with the selinuxuser_execstack boolean, that would provide enough flexibility to solve most SELinux problems between cron and logrotate.

For the record, we already have cron_userdomain_transition:

~] sesearch -b cron_userdomain_transition -p transition -AC
Found 6 semantic av rules:
ET allow crond_t sysadm_t : process transition ; [ cron_userdomain_transition ]
ET allow crond_t unconfined_t : process transition ; [ cron_userdomain_transition ]
DF allow crond_t unconfined_cronjob_t : process transition ; [ cron_userdomain_transition ]
ET allow crond_t openshift_domain : process transition ; [ cron_userdomain_transition ]
ET allow crond_t staff_t : process transition ; [ cron_userdomain_transition ]
ET allow crond_t user_t : process transition ; [ cron_userdomain_transition ]


But that is not quite what I want.

So yeah, a cron_logrotate_transition_disabled boolean would be welcome.

Comment 7 Lukas Vrabec 2018-04-25 10:58:16 UTC
(In reply to Radosław Piliszek from comment #5)
> I believe a boolean would give a false sense of higher security. I did some
> policy mining and found that:
> 
> There is already a rule:
> 
> allow logrotate_t domain : process signal ;
> 
> which essentially allows logrotate to send signals other than SIGKILL,
> SIGSTOP or SIGCHLD to virtually any other process (since all domain types
> should have domain attribute). So, well, adding systemd stopping would not
> be that bad (in fact only adding SIGKILL, SIGSTOP and SIGCHLD signals for
> systemd-managed services). :-)
> 
> In other words - logrotate scripts are already highly privileged with root
> user and wide permissions from SELinux.

Agree here, I don't see any real value to have this in boolean. I'll allow this access.

Comment 8 Lukas Vrabec 2018-04-25 10:58:57 UTC
(In reply to Benjamin Lefoul from comment #6)
> (In reply to Lukas Vrabec from comment #4)
> > We can do boolean for this. It makes sense to me.
> 
> Lukas, I also think some additional boolean tuning for logrotate would be
> very welcome in the policy.
> 
> I, too, am experiencing SELinux denials because of the relationship between
> cron and logrotate. In my case, crond_t transitions to system_cronjob_t by
> executing the following bin_t file:
> 
> ~] ll -Z /etc/cron.daily/logrotate 
> -rwx------. root root system_u:object_r:bin_t:s0      
> /etc/cron.daily/logrotate
> 
> See:
>    allow system_cronjob_t bin_t : file { ioctl read getattr lock execute
> execute_no_trans entrypoint open } ; 
>    allow crond_t system_cronjob_t : process transition ; 
>    allow crond_t bin_t : file { ioctl read getattr lock execute
> execute_no_trans open } ; 
> 
> However, /etc/cron.daily/logrotate does call explicitely
> "/usr/sbin/logrotate /etc/logrotate.conf", the only logrotate_exec_t on my
> system btw:
> 
> ~] find / -context "*logrotate_exec_t*"
> /usr/sbin/logrotate
> 
> Both crond_t and system_cronjob_t can execute that:
>    allow system_cronjob_t logrotate_exec_t : file { read getattr execute
> open } ; 
>    allow crond_t logrotate_exec_t : file { read getattr execute open } ; 
> 
> ...to transition into logrotate_t:
>    allow logrotate_t logrotate_exec_t : file { ioctl read getattr lock
> execute execute_no_trans entrypoint open } ; 
>    allow system_cronjob_t logrotate_t : process transition ; 
>    allow crond_t logrotate_t : process transition ; 
> 
> /etc/logrotate.conf in turn includes config found in /etc/logrotate.d, among
> which a file with a "postrotate" instruction calling another script in my
> system, which in turn had to execute something with "execstack" (I know,
> that's bad, but I have no control over this).
> 
> Ah, but that is one thing logrotate_t cannot do when system_cronjob_t (and
> crond_t) can, look:
> 
> ~] sesearch -s crond_t -AC | grep execstack
> ET allow crond_t crond_t : process execstack ; [ selinuxuser_execstack ]
> ~] sesearch -s system_cronjob_t -AC | grep execstack
> ET allow system_cronjob_t system_cronjob_t : process execstack ; [
> selinuxuser_execstack ]
> ~] sesearch -s logrotate_t -AC | grep execstack
> ~]
> 
> 
> So a solution for me was to edit /etc/cron.daily/logrotate and use runcon by
> replacing:
> "/usr/sbin/logrotate /etc/logrotate.conf" with:
> "runcon -t system_cronjob_t /usr/sbin/logrotate /etc/logrotate.conf"
> 
> Obviously I don't like having to use runcon in an executable in my
> centralized config management tool.
> 
> It would have been nice to have a boolean such as
> cron_logrotate_transition_disabled to prevent system_cronjob_t and crond_t
> to transition to logrotate_t (execute_no_trans?). Combined with the
> selinuxuser_execstack boolean, that would provide enough flexibility to
> solve most SELinux problems between cron and logrotate.
> 
> For the record, we already have cron_userdomain_transition:
> 
> ~] sesearch -b cron_userdomain_transition -p transition -AC
> Found 6 semantic av rules:
> ET allow crond_t sysadm_t : process transition ; [
> cron_userdomain_transition ]
> ET allow crond_t unconfined_t : process transition ; [
> cron_userdomain_transition ]
> DF allow crond_t unconfined_cronjob_t : process transition ; [
> cron_userdomain_transition ]
> ET allow crond_t openshift_domain : process transition ; [
> cron_userdomain_transition ]
> ET allow crond_t staff_t : process transition ; [ cron_userdomain_transition
> ]
> ET allow crond_t user_t : process transition ; [ cron_userdomain_transition ]
> 
> 
> But that is not quite what I want.
> 
> So yeah, a cron_logrotate_transition_disabled boolean would be welcome.

Could you please create new bug related your issues? 
Thanks.

Comment 10 Benjamin Lefoul 2018-09-10 11:51:37 UTC
(In reply to Lukas Vrabec from comment #8)
> (In reply to Benjamin Lefoul from comment #6)
> > (In reply to Lukas Vrabec from comment #4)
> > > We can do boolean for this. It makes sense to me.
> > 
> > Lukas, I also think some additional boolean tuning for logrotate would be
> > very welcome in the policy.
> 
> Could you please create new bug related your issues? 
> Thanks.

Okay: https://bugzilla.redhat.com/show_bug.cgi?id=1627075

Comment 13 errata-xmlrpc 2018-10-30 10:02:20 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, 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-2018:3111