How and why Linux daemons drop privileges

How and why Linux daemons drop privileges

In this article we have a look at the privileges of Linux daemons and dropping privileges in particular. The samples provided are in C.

Why drop privileges?

Some daemons need root permissions to start. This happens for example when a daemon wants to bind to a low port (<1024). However running network based daemons with root permissions is considered to be a serious risk. In case of compromise of the process, an attacker has full access to the system. This is why software like nginx starts with a master process and forks non-privileged child processes. These child processes (or workers), run under the context of non-privileged account like www-data.

root      2034     1  0 Jun10 ?        00:00:00 nginx: master process /usr/sbin/nginx
www-data  2036  2034  0 Jun10 ?      00:00:35 nginx: worker process
www-data  2037  2034  0 Jun10 ?        00:00:36 nginx: worker process
www-data  2038  2034  0 Jun10 ?        00:00:33 nginx: worker process
www-data  2039  2034  0 Jun10 ?        00:00:37 nginx: worker process

How to drop privileges

First the program needs to check its current user ID. If it is zero, the equal of root, then it should drop both the user ID and group ID. This can be done with the setuid and setgid functions.

if (getuid() == 0) {
/* process is running as root, drop privileges */

 

if (setuid(userid) != 0)
fatal(“setuid: Unable to drop user privileges: %S”, strerror(errno));
if (setgid(groupid) != 0)
fatal(“setgid: Unable to drop group privileges: %s”, strerror(errno));
}

Once a process has switched to a non-privileged user, it should not be able to regain root permissions. This can be tested with the following snippet:

if (setuid(0) != -1)
fatal(“ERROR: setuid back to zero succeeded, quitting as this is a security risk”);

If it succeeds for what reason, the program should terminate.

Additional groups

The root account may also be part of supplementary groups, besides the usually root or wheel group. With the help of the function initgroups, any of the supplementary groups of the root user can be dropped. This way the process can’t access any data by accident.

Current work directory

When starting a process, the current work directory might still be something owned by the root user. For safety, the chdir function can be used to move to another safe work directory. Usually this will be the home directory or data directory.

Capabilities

Another way to provide only limited privileges to a binary, is giving them capabilities. This is implemented in the Linux kernel and splits all different “roles” the root user can have. Examples include this earlier mentioned binding to a low port, open network sockets or loading a kernel module. For daemons it is not wise to run fully under the root context, but you might want to use the capability to open up a port.

For more information about how capabilities work, see our Linux capabilities 101 post.

Conclusion

Safe programming takes a lot of effort, but helps not in introducing weaknesses into software, systems and our valuable data. After all it is this same data which needs to be protected, hence every effort is another useful step in achieving this important goal.

Lynis Enterprise

Lynis Enterprise screenshot to help with system hardening

This blog post is part of our Linux security series and the mission to get Linux and Unix-based systems more secure.

Does system hardening take a lot of time, or do you have any compliance in your company? Have a look at Lynis Enterprise.

Or start today with the open source security scanner Lynis (GitHub)


5 comments

  • bb

    Thank You

    Reply
  • Gerry CohnGerry Cohn

    A correction to the following sentence is required:
    Safe programming takes a lot of effort, but helps in introducing weaknesses into software, systems and our valuable data.

    It probably should read:
    Safe programming takes a lot of effort, but helps in NOT introducing weaknesses into software, systems and our valuable data.

    Reply
  • Märt BMärt B

    you should setgid before setuid – you won’t have permissions to call setgid after dropping privileges

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *