There appears to be a generic problem with "pidof -c" under SELinux enforcing which has the side-effect of confusing some of the init.d scripts.
In particular, the following services - at least - fail to shut down or report status cleanly:
acpid hidd vsftpd smartd autofs mcstrans syslog-ng ( but not syslogd .. )
The common feature is that these daemons lack a corresponding /var/run/<daemonname>.pid; in the case of syslog-ng, of course, the real pid has the "wrong" name.
During shutdown, /etc/init.d/functions:killproc() searches for the pidfile, and if it fails to find one, it searches for a pid with a matching exec name via the __pids_pidof() function.
... # Output PIDs of matching processes, found using pidof __pids_pidof() { pidof -c -o $$ -o $PPID -o %PPID -x "$1" || \ pidof -c -o $$ -o $PPID -o %PPID -x "${1##*/}" } ...
When invoked in SELinux permissive, all is well, and the correct pid is located, but under enforcing, ( selinux-policy-strict-2.4.6-27 in my case), "pidof -c" returns a null string. This in turn, causes killproc to assume that the service is dead.
FWIW, FC4/strict/enforcing is Ok where pidof has a -c option, whilst RHEL4 doesn't appear to have a -c option to pidof anyway.
The latest pidof appears to use readlink() to compare the value of /proc/<pid>/exe for any matching pids - older pidof's used stat().
Needless to say, logs don't show any AVC's when I try to run the rogue pidof calls.
By way of example, one can read the basic process list from sysadm_t, and then show that pidof -c -x fails where pidof -x works. Similarly, I've used run_init to emulate the behaviour of the boot scripts running pidof:
[root@topaz ~]# ps axZ | grep smartd system_u:system_r:fsdaemon_t 2871 ? S 0:00 /usr/sbin/smartd -q never staff_u:sysadm_r:sysadm_t 3375 pts/0 R+ 0:00 grep smartd [root@topaz ~]# [root@topaz ~]# pidof -x /usr/sbin/smartd 2871 [root@topaz ~]# pidof -x smartd 2871 [root@topaz ~]# [root@topaz ~]# pidof -c -x /usr/sbin/smartd
[root@topaz ~]# pidof -c -x smartd
[root@topaz ~]# run_init pidof -c -x /usr/sbin/smartd Authenticating root. Password:
[root@topaz ~]# [root@topaz ~]# run_init pidof -x /usr/sbin/smartd Authenticating root. Password: 2871 [root@topaz ~]#
As a variant on these tests, I've tried to directly ls and readlink the exe in question; ls fails to read the symlink and errors, whilst readlink silently returns with a null.
[root@topaz ~]# ls -ldZ /proc/2871/exe ls: cannot read symbolic link /proc/2871/exe: Permission denied lrwxrwxrwx root root system_u:system_r:fsdaemon_t /proc/2871/exe [root@topaz ~]# run_init ls -ldZ /proc/2871/exe Authenticating root. Password: lrwxrwxrwx root root system_u:system_r:fsdaemon_t /proc/2871/exe [root@topaz ~]#
[root@topaz ~]# run_init ls -lZ /proc/2871/exe Authenticating root. Password: ls: /proc/2871/exe: Permission denied
[root@topaz ~]# readlink /proc/2871/exec [root@topaz ~]#
[root@topaz ~]# run_init readlink /proc/2871/exec Authenticating root. Password: [root@topaz ~]#
As a workround for the present, I've simply removed the -c option from /etc/init.d/functions:__pids_pidof()
I'm currently running:
selinux-policy-strict-2.4.6-27.fc6 kernel-2.6.18-1.2869 SysVinit-2.86-14
Should this be logged as a bug under SELinux policy or SysVinit?
Does this bug affect targeted policy as well?
Is there some simple extra permission which could be granted to initrc_t and sysadm_t which would let them perform readlink /proc/<pid>/exe, and hence pidof -c ?
On Fri, 2007-01-19 at 15:05 +0000, Ted Rule wrote:
There appears to be a generic problem with "pidof -c" under SELinux enforcing which has the side-effect of confusing some of the init.d scripts.
In particular, the following services - at least - fail to shut down or report status cleanly:
acpid hidd vsftpd smartd autofs mcstrans syslog-ng ( but not syslogd .. )
The common feature is that these daemons lack a corresponding /var/run/<daemonname>.pid; in the case of syslog-ng, of course, the real pid has the "wrong" name.
During shutdown, /etc/init.d/functions:killproc() searches for the pidfile, and if it fails to find one, it searches for a pid with a matching exec name via the __pids_pidof() function.
... # Output PIDs of matching processes, found using pidof __pids_pidof() { pidof -c -o $$ -o $PPID -o %PPID -x "$1" || \ pidof -c -o $$ -o $PPID -o %PPID -x "${1##*/}" } ...
When invoked in SELinux permissive, all is well, and the correct pid is located, but under enforcing, ( selinux-policy-strict-2.4.6-27 in my case), "pidof -c" returns a null string. This in turn, causes killproc to assume that the service is dead.
FWIW, FC4/strict/enforcing is Ok where pidof has a -c option, whilst RHEL4 doesn't appear to have a -c option to pidof anyway.
The latest pidof appears to use readlink() to compare the value of /proc/<pid>/exe for any matching pids - older pidof's used stat().
Needless to say, logs don't show any AVC's when I try to run the rogue pidof calls.
By way of example, one can read the basic process list from sysadm_t, and then show that pidof -c -x fails where pidof -x works. Similarly, I've used run_init to emulate the behaviour of the boot scripts running pidof:
[root@topaz ~]# ps axZ | grep smartd system_u:system_r:fsdaemon_t 2871 ? S 0:00 /usr/sbin/smartd -q never staff_u:sysadm_r:sysadm_t 3375 pts/0 R+ 0:00 grep smartd [root@topaz ~]# [root@topaz ~]# pidof -x /usr/sbin/smartd 2871 [root@topaz ~]# pidof -x smartd 2871 [root@topaz ~]# [root@topaz ~]# pidof -c -x /usr/sbin/smartd
[root@topaz ~]# pidof -c -x smartd
[root@topaz ~]# run_init pidof -c -x /usr/sbin/smartd Authenticating root. Password:
[root@topaz ~]# [root@topaz ~]# run_init pidof -x /usr/sbin/smartd Authenticating root. Password: 2871 [root@topaz ~]#
As a variant on these tests, I've tried to directly ls and readlink the exe in question; ls fails to read the symlink and errors, whilst readlink silently returns with a null.
[root@topaz ~]# ls -ldZ /proc/2871/exe ls: cannot read symbolic link /proc/2871/exe: Permission denied lrwxrwxrwx root root system_u:system_r:fsdaemon_t /proc/2871/exe [root@topaz ~]# run_init ls -ldZ /proc/2871/exe Authenticating root. Password: lrwxrwxrwx root root system_u:system_r:fsdaemon_t /proc/2871/exe [root@topaz ~]#
[root@topaz ~]# run_init ls -lZ /proc/2871/exe Authenticating root. Password: ls: /proc/2871/exe: Permission denied
[root@topaz ~]# readlink /proc/2871/exec [root@topaz ~]#
[root@topaz ~]# run_init readlink /proc/2871/exec Authenticating root. Password: [root@topaz ~]#
As a workround for the present, I've simply removed the -c option from /etc/init.d/functions:__pids_pidof()
I'm currently running:
selinux-policy-strict-2.4.6-27.fc6 kernel-2.6.18-1.2869 SysVinit-2.86-14
Should this be logged as a bug under SELinux policy or SysVinit?
Does this bug affect targeted policy as well?
Is there some simple extra permission which could be granted to initrc_t and sysadm_t which would let them perform readlink /proc/<pid>/exe, and hence pidof -c ?
Changes in the kernel (separate from selinux) altered permission checking on proc such that ptrace checks are applied pervasively when accessing another task's /proc/pid entries (this was done as part of the containers work). Thus, policy has to allow ptrace permission between the respective domains to support such accesses (and these are usually covered up by dontaudit rules to suppress noise on e.g. ps -el and the like).
In the future, I'd like to see proc permission checking revised to distinguish read-only access to process state vs. full ptrace access.
Stephen Smalley wrote:
In the future, I'd like to see proc permission checking revised to distinguish read-only access to process state vs. full ptrace access.
That would have to be much more detailed than just read/writer vs read-only. ptrace reads can leak information (especially a no-no for MLS but also for normal operation). For instance, you don't want to allow poking a process to get randomization values/seeds like the one used for pointer encryption.
So, you'd have to go into great detail and maybe even split the functionality of a single ptrace or /proc operation in minute parts which might or might not be allowed.
On Fri, 2007-01-19 at 11:11 -0800, Ulrich Drepper wrote:
Stephen Smalley wrote:
In the future, I'd like to see proc permission checking revised to distinguish read-only access to process state vs. full ptrace access.
That would have to be much more detailed than just read/writer vs read-only. ptrace reads can leak information (especially a no-no for MLS but also for normal operation). For instance, you don't want to allow poking a process to get randomization values/seeds like the one used for pointer encryption.
So, you'd have to go into great detail and maybe even split the functionality of a single ptrace or /proc operation in minute parts which might or might not be allowed.
Understood, but the current situation leads to overly permissive policy (or excessive use of dontaudits and limited functionality) just to give some visibility into the process state. Having to allow domain A full ptrace control over domain B just to let domain A see some of domain B's /proc/pid state is overkill.
selinux@lists.fedoraproject.org