When running logwatch from /etc/crontab with vixie-cron (as opposed to running from command line) logwatch needs the ability to read files in the associated user's (typically root) home area. When these permissions are denied logwatch will not clean up it's temporary files or directories and prepends an error/warning message to each report. The list of files in this message continues to grow until the administrator intervenes by manually deleting the listed directories. Here is an example /etc/crontab entry: 5 0 * * * root /usr/sbin/logwatch.pl Here is an example message from logwatch: You have old files in your logwatch tmpdir (/var/cache/logwatch): logwatch.0171KPXd logwatch.i71fKOSC logwatch.BePGgN1Q The directories listed above were most likely created by a logwatch run that failed to complete successfully. If so, you may delete these directories. Here are some avc denials once dontaudit rules were disabled as these denials are currently dontaudited. These were taken from two different runs as I was tracking down the exact permissions that are required: Nov 29 20:30:06 siren kernel: type=1400 audit(1322623806.438:8061): avc: denied { getattr } for pid=12387 comm="sh" path="/root" dev=sda1 ino=4290561 scontext=system_u:system_r:logwatch_t tcontext=root:object_r:user_home_dir_t tclass=dir Nov 29 20:30:06 siren kernel: type=1400 audit(1322623806.438:8062): avc: denied { search } for pid=12387 comm="sh" name="root" dev=sda1 ino=4290561 scontext=system_u:system_r:logwatch_t tcontext=root:object_r:user_home_dir_t tclass=dir Nov 30 17:30:02 siren kernel: type=1400 audit(1322699402.120:3264086): avc: denied { read } for pid=26604 comm="logwatch.pl" name="root" dev=sda1 ino=4290561 scontext=system_u:system_r:logwatch_t tcontext=root:object_r:user_home_dir_t tclass=dir
Created attachment 294409 [details, diff] Patch to allow logwatch read permissions
I'm currently inclined to say this is a bug (although fedora has implemented a similar patch for logwatch in their repository without much ado, their developer too found it strange). I tried to reproduce as follows: emerge logwatch and selinux-logwatch, mark /usr/sbin/logwatch.pl as logwatch_exec_t (yes, the context in the module is wrong) and have the following crontab entry (in /etc/crontab): * * * * * root /usr/sbin/logwatch.pl | cat > /tmp/cron/listing 2>&1 The /tmp/cron directory is crond_tmp_t so that the system_cronjob_t domain can write its output there (so that I can see if logwatch.pl works properly and, if not, what the error would be that it spews) I couldn't reproduce. The process correctly runs as logwatch_t too. Did you have any changes in the configuration? Perhaps a configuration that launches a shell (which might then be responsible for reading from the executing users' home directory)?
Oddly enough the problem ONLY occurs when it is run from /etc/crontab. (Maybe cron is launching an intermediate shell??) I didn't try your method of launching logwatch, however. Running from a command line it works normally -- I couldn't make it fail no matter what I tried. I've posted my /etc/logwatch/conf/logwatch.conf (minus all comments) file below for your reference, though I don't think there is much difference from a default (gentoo) setup. I did try commenting the MailTo and using Print=Yes instead, but it still gave the same error. I did have to mark /usr/sbin/logwatch.pl as logwatch_exec_t I put in a rule using semanage so it wouldn't get changed and I forgot about doing it, else I would have mentioned it and posted a patch to the .fc file. Perhaps there is a service running on my system where one or more of the logwatch scripts use a shell. One other thing I thought about, but didn't test was allowing the siginh, rlimitinh, and noatsecure permissions for system_cronjob_t -> logwatch_t (might not be remembering those avc's right) instead of reading the home area. That might be worth a shot, maybe?? LogDir = /var/log TmpDir = /var/cache/logwatch MailTo = root MailFrom = root Print = No Range = yesterday Detail = Med Service = All Service = "-zz-network" Service = "-zz-sys" mailer = "/usr/sbin/sendmail -t" And, just for further reference: system_u:object_r:logwatch_cache_t /var/cache/logwatch/
If the logwatch entry works with the patch you suggested, then there is no reason to look at the three others (rlimitinh etc.) The reason that running it commandline works is because it does not trigger a transition then (sysadm_t -> logwatch_t is no valid transition). As a result, the script continues to run as sysadm_t, which of course has many more privileges than logwatch_t. I'll try to set up my local mailing system again so I can capture the output through the system cron mails. Perhaps it has indeed something to do with that.
Okay, I still can't reproduce this. logwatch (without output catching) works just fine here within cron. The mails sent contain the logwatch output and I don't have stale files laying around...
hmmmm..... I'm wondering about your "without output catching" (caching)?? Is that something that you specifically enabled/disabled? I did a quick search and poked around a bit but didn't find anything
I meant without any output redirection defined in the crontab, so the output of the command is caught by the cronjob session itself and mailed to the (root) user.
I've backed out my patch locally and am trying to dig for more info about where/why the problem is happening. Thus far I've only been able to get perl to spit out the following: cannot stat initial working directory for /root: Permission denied at /usr/lib64/perl5/5.12.4/File/Temp.pm line 902 This particular module is part of the perl core language itself: equery b /usr/lib64/perl5/5.12.4/File/Temp.pm * Searching for /usr/lib64/perl5/5.12.4/File/Temp.pm ... dev-lang/perl-5.12.4-r1 (/usr/lib64/perl5/5.12.4/File/Temp.pm) The above error message appears near the end of the output and is randomly inserted as a result of IO buffering. It appears somewhere in the last service script run, no matter which ones are enabled||disabled||applicable to the system. Also the above info indicates the potential for other perl programs/scripts run from cron to have similar difficulties, but what those would be, if any, I have no idea. ;) Still digging..........
I was able to dig up the following: The error message: cannot stat initial working directory for /root: Permission denied at /usr/lib64/perl5/5.12.4/File/Temp.pm line 902 is coming from the cleanup routine which happens at exit as a result of the call to Temp.pm by logwatch Ultimately Temp.pm uses the remove_tree() function inside File::Path, which ultimately makes a call to /bin/pwd from a child shell. It is this call which is failing and the error exit is being pushed upwards all the way to logwatch. Now MY BAD here, I have not to this point mentioned (at least in this bug) that I am running a strict policy with ubac constraints. With that in mind, I would fully expect selinux to return a permission denied to any process domain trying to read a home area that had not been given explicit permission. Unless, of course, I have now been digging so deep and for so long I have tunnelled my way out to left field!
Correction: It isn't the call to /bin/pwd that is failing, it is the stat() that immediately follows.
But here, Temp.pm already mentions that this might occur and as such transforms this into a warning: 896 foreach my $dir (@dirs) { 897 if (-d $dir) { 898 # Some versions of rmtree will abort if you attempt to remove 899 # the directory you are sitting in. We protect that and turn it 900 # into a warning. We do this because this occurs during 901 # cleanup and so can not be caught by the user. 902 eval { rmtree($dir, $DEBUG, 0); }; 903 warn $@ if ($@ && $^W); 904 } 905 } I notice that my mails (from con), yield: X-Cron-Env: <HOME=/> An "echo ${PWD}" in cron gives me "/". Does it, on your side, say "/root" ?
The error is actually being raised inside Path.pm in remove_tree(), which gets called by rmtree() that is wrapped in the eval in Temp.pm. Furthermore Path.pm states that it will not attempt to delete anything if the stat() isn't successful. cannot stat initial working directory: [errmsg] "remove_tree" attempted to stat the initial directory (after having successfully obtained its name via "getcwd"), however, the call failed for some reason. No attempt will be made to delete anything. echo ${PWD} when run from cron on my system returns /root Several environment variables are set up automatically by the cron(8) daemon. SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd line of the crontab's owner. HOME and SHELL may be over‐ ridden by settings in the crontab; LOGNAME may not. I tried setting HOME=/ in my crontab and logwatch ran fine and did not leave a stale file. So now the question is which of these is better security practice, setting HOME=/ in /etc/crontab or leaving it undefined and allowing cron to pull it from the passwd file and pass HOME=/root to logwatch and other jobs it runs? If the former, it might be good to document the need/recommendation for setting HOME=/ somewhere in Gentoo's SELinux handbook. Or if they are deemed equally valid, then we at least have a good understanding of why logwatch needs the permission.
The "HOME=/" setting in /etc/crontab is, afaik, the default one in Gentoo. If things need to run for the root user, I think the idea is that the root user uses his own crontab for that (/var/spool/cron/crontabs/*) which, for SELinux support of cron, also means that this is for user jobs, not system jobs. I'll ask around and see what the SELinux folks in general think. I can have the necessary privileges added in the cron_system_entry (which then ensures that all domains that are identified as domains that can be ran from within cron have this privilege), but I am not certain that this is acceptable security-wise.
Well you are right, HOME=/ is the default. I dug around and found a copy of /etc/crontab on my system that portage had installed when I first migrated to Gentoo. At that time, I was using /var/spool/cron/crontabs for root and just tucked that file away for future reference if I ever needed it, and forgot about it till now. **sigh**
Well, if I do not get proper feedback from [1] I'm going to document this on [2]. After all, it isn't a functionality requirement of logwatch but rather a "circumstantial" setting. [1] http://oss.tresys.com/pipermail/refpolicy/2011-December/004845.html [2] http://www.gentoo.org/proj/en/hardened/selinux/modules/cron.xml
Updating cron.xml information
Moved module information to the wiki: http://wiki.gentoo.org/wiki/SELinux/cron
Documentation updated