SELinux team works to remove DAC_OVERRIDE Permissions.

DAC_OVERRIDE is one of the most powerful capabilities, and most app developers don't understand when they are taking advantage of it, or how easy it is to eliminate the need.

What is DAC_OVERRIDE?

man capabilities

...

       CAP_DAC_OVERRIDE

              Bypass file read, write, and execute permission checks.  (DAC is an abbreviation of "discretionary access control".)

Looking at /usr/include/linux/capability.h

#define CAP_DAC_OVERRIDE     1

/* Overrides all DAC restrictions regarding read and search on files and directories, including ACL restrictions if [_POSIX_ACL] is defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */

Giving a process this access means it can ignore file system permission checks. Admittedly everyone thinks root can do this by default anyways, but if you can eliminate this access from a system service, you really can tighten the security.  

SELinux

SELinux ignores DAC permissions, it does not care if a a processes is running as root or any other UID.  The only part of SELinux that concerns itself with UID/GID permissions is in linux capabilities like DAC_OVERRIDE.

With SELinux we often look at what process types require DAC_OVERRIDE and try to figure out if we can rid of the access.  

Usually services that need DAC_OVERRIDE run as a root process for a short time before becoming non root.  Since they are going to run as non root they set up permissions on directories or unix domain sockets to be accessible by the UID/GID pair the service is going to run with.   Often they accidentally or intentionally remove `root UID` access, thinking this will give them better security.  IE if I only want the UID of my process to access an object, I set the object permissions such that only its UID can access it.

Lets look at an example, I create a directory named myapp, and set the ownership and group to my UID/GID 3267 (My UID), now I also set the permissions to 770.

ls -ld /var/lib/myapp
drwxrwx---. 2 dwalsh dwalsh 6 May 28 06:55 /var/lib/myapp

 Now processes running as root are NOT allowed to create any content in this directory, or to execute any content in this directory without using DAC_OVERRIDE.  (Note: It might be able to see and traverse the directory using DAC_READ_SEARCH, but that is a story for another blog).

The simplest way to allow the root process to get full access this directory would be to change the group ownership to root.

chown 3267:0 /var/lib/myapp
# ls -ld /var/lib/myapp
drwxrwx---. 2 dwalsh root 6 May 28 06:55 /var/lib/myapp

The root process gets full access to the directory using its group permissions and processes running as 'dwalsh'  get full access running as that UID using its owner permissions.  

While this does not seem that significant from a DAC point of view, after all root processes has full access to all objects owned by UID=0, in an SELinux world you would be running as myapp_t, and might only have access to the file system objects labeled my myapp_t, if we can drop the DAC_OVERRIDE permissions from SELinux we can really tighten up the security.

Lets look at a real world example via the following bugzilla. 

When dovecot sets up a socket for mail clients to talk to, it sets up the permssions on the socket to be:

# ls -l /var/run/dovecot/login/ipc-proxy
srw-------. 1 dovenull root 0 May 27 12:34 /var/run/dovecot/login/ipc-proxy

This permission means that only process running as the 'dovenull' user can communicate with the socket.  At somepoint when dovecot, running as dovecot_t, is coming up, the 'root' process attempts to access the ipc-proxy socket and is denied by SELinux.  

type=AVC msg=audit(1526480141.321:6579): avc:  denied  { dac_override } for  pid=19839 comm="dovecot" capability=1  scontext=system_u:system_r:dovecot_t:s0 tcontext=system_u:system_r:dovecot_t:s0 tclass=capability permissive=0

The simple thing to do from an SELinux point of view would be to add the allow rule

allow dovecot_t self:capability dac_override;

But from a security proint of view, this is lousy.  The much better solution would be to 'relax' the permissions on the socket by adding group read/write.

# ls -l /var/run/dovecot/login/ipc-proxy
srwrw-----. 1 dovenull root 0 May 27 12:34 /var/run/dovecot/login/ipc-proxy

Now root processes are allowed to access the socket via DAC permissions and no longer need to use linux capabilities to access the socket.  This would be a far more secure way of running Dovecot and really involved a minor change to the code.

When I look at containers, we allow DAC_OVERRIDE by default, because so many containers are badly written, but I think it would be great for us to be able to remove this permission by default.

podman run -d --cap-drop DAC_OVERRIDE myimage  

Or for those of you still using Docker

docker run -d --cap-drop DAC_OVERRIDE myimage  

I will talk more about this in a future blog.

Bottom Line:

In most cases the requirement for DAC_OVERRIDE is a simple programmer error in the way he sets up his application and can be fixed by adjusting the permissions/ownership on file system objects.  Loosening the SELinux constraints should be the last resort.


Error

Anonymous comments are disabled in this journal

default userpic

Your reply will be screened