Red Hat Bugzilla – Bug 126259
logrotate directly execs scripts located in /tmp however /tmp might be mounted noexec
Last modified: 2007-11-30 17:10:44 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6)
Description of problem:
logrotate runs rotate scripts by writing the script out to /tmp with
!#/bin/bash prepended and then exec'ing them. However, there is no
guarantee that /tmp is mounted to allow exec. Previous versions of
logrotate used system() to run these scripts, which ran these scripts
indirectly via a shell.
Either the calls should be changed back to system() or else logrotate
should exec /bin/sh to run the script, it should not attempt to run
these directly - it's wholly unneccessary given that logrotate already
obviously knows the location of the shell and it breaks on systems
with /tmp mounted noexec and the script will be run with same
I'm attaching the obvious fix for this problem (not tested).
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. mount -o remount,noexec /tmp
2. run logrotate
3. observe output
Actual Results: You get error to say script(s) did not run.
daemons such as syslogd and httpd no longer write logging to any
meaningful file descriptors as they depend on the logrotate embedded
scripts to tell them to reopen logs.
you lose many hours of critical logging information until you notice
problem and manually HUP/USR1 the daemons concerned.
Expected Results: I expect the damn thing to do its job correctly and
not depend on /tmp being mounted exec as if it were some naive
Created attachment 101237 [details]
exec /bin/sh to run scripts rather than expecting chmod 0700 in /tmp and exec to work
- execlp a shell with the script in /tmp as argument
- remove now unneeded write out of a #!/bin/sh line
- remove now unneeded chmod 0700 of the tmp script file
Not good. As of execlp(3) man page says an execlp("/bin/sh",filespec, logfn, NULL); is not
good because it calls /bin/sh with the name filespec (arg0), and logfn as first parameter.
The same is true for the original version (see bug 126490).
Oops yes. I did say I hadnt tested the patch ;)
Personally, I think logrotate should revert back to using system(),
which was the other alternative mentioned in this patch. I dont see
why this was changed in logrotate. it fixes nothing but it breaks things.
If there is a requirement to support noexec /tmp, it needs to be sold
a bit more widely before asking for changes to accomodate it. Right
now, I think it's safe to assume that things on /tmp can be executed,
so I don't see the pressing need for the logwatch patch. Comments
I dont see why it needs to be sold.
I have had /tmp as noexec for years, ever since I had a (then RH7.3)
machine infected by the mod_ssl/apache worm (slapper?), which depended
on /tmp being executable - noexec would have prevented the worm
payload from being run. *nothing* legitimate has ever assumed /tmp to
be mounted exec. A *change* to logwatch *introduces* this assumption. So:
- years of running /tmp noexec without problem
- only recent logwatch has a problem
- the change to logwatch introducing the problem appears not to have
any beneficial effect.
I therefore assert that if anything needs to be "sold" it is the
suggestion that we *add* the assumption of exec()'ability to /tmp.
The information given, and the needs of the vast majority of users,
don't currently justify applying the patch. Systems customized with
noexec will have to fix things on their own...
A silly churn change to logwatch that has no practical effect other
than to break noexec /tmp and the problem is with noexec? Sorry that
makes 0 sense.
I'm guessing that what you meant to say is "go bug upstream to fix
it". ;) That would make sense, and that's what I now intend to do.
1. I'm guessing the logwatch developers had some notion that they were
adding to "security" because system() is, as we all know, evil. But
their change just does the equivalent of system() inside the process,
the script is a trusted one anyway by definition, they dont clear
environment variables before exec (which, anyway, would work for
sanitising system() too), etc. Net result is 0 difference, other than
to mess up noexec /tmp.
We're using noexec too, for exactly the same reasons as Paul, because
we still have much the same scars from being bitten by an Apache based
worm. Making sure any directory that Apache can write to is mounted
noexec stops such things in their tracks.
We've been scratching our heads for a while trying to figure out why
our log rotation postprocessing scripts stopped working after
upgrading to FC2, stuffing up usage charging and log monitoring.
So telling me that it's OK to change logrotate in a way that breaks
running systems and not fix it doesn't sit too well with me. We're
going to have to ditch logrotate and use something else, because
bitter experience tells us that turning off noexec is not an option.
It IS a bug. Fix it.
Created attachment 106293 [details]
The corrected patch for logrotate.
Created attachment 106294 [details]
Spec file which uses the corrected patch for logrotate.
Here's another vote for fixing this in whatever way is deemed appropriate.
If logrotate source needs to be changed, so be it. I agree that
depending on /tmp being executable is quite silly, any partitions that
can have their mount flags restricted should have this done whenever
possible, and /tmp has long been a candidate for exactly such an option.
My quickie fix is to set "TMPDIR=/var/tmp; export TMPDIR" in
/etc/cron.daily/logrotate, because /var is not mounted noexec for me.
But if it were, then AFAICT I'd need to set TMPDIR in prerotate
sections of each logrotate config file.. a major pain.
For the next happy traveler who trips across this issue, it took years but
logrotate no longer makes this same "naive script-kiddy worm" assumption (bug
156594 / RHBA-2006-0696).