Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Linux Kernel Capabilities Explained

DZone 's Guide to

Linux Kernel Capabilities Explained

In this article, we take a quick look at Linux Kernel's permission processes and show you how to use them to keep your web page or app secure.

· Security Zone ·
Free Resource

Traditionally, Linux Kernel distinguishes its processes with the following two categories:

  • Privileged Processes: These processes allow the user to bypass all Kernel permission checks.

  • Unprivileged Processes: These processes are subject to full permission checks, such as the effective UID, GID, and supplementary group list.

Granting full privileged access to a user process might induce system abuse, like unauthorized changes of data, backdoors, changing ACL, etc.

Linux 2.2 shipped with a solution called Capabilities. Capabilities allows the developer to grant binaries/files specific permissions.

Example

Let's say we want to start a Simple HTTP Server module of Python on port 80 with a non-privileged user. If we try to start the process without granting any capabilities, we will get the following error:

anshulp@dzone-vagrant-box:$ python -m SimpleHTTPServer 80
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/usr/lib/python2.7/SimpleHTTPServer.py", line 235, in <module>
    test()
  File "/usr/lib/python2.7/SimpleHTTPServer.py", line 231, in test
    BaseHTTPServer.test(HandlerClass, ServerClass)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 606, in test
    httpd = ServerClass(server_address, HandlerClass)
  File "/usr/lib/python2.7/SocketServer.py", line 417, in __init__
    self.server_bind()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 108, in server_bind
    SocketServer.TCPServer.server_bind(self)
  File "/usr/lib/python2.7/SocketServer.py", line 431, in server_bind
    self.socket.bind(self.server_address)
  File "/usr/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 13] Permission denied

Let's add the CAP_NET_BIND_SERVICE capability to our Python binary.

sudo setcap 'CAP_NET_BIND_SERVICE+ep' /usr/bin/python2.7 

The above command states that we are adding the  CAP_NET_BIND_SERVICE  capability to our /usr/bin/python2.7 file. +ep indicates that the file is Effective and Permitted ( "-"  would remove it).

Now let's try to run the Python Simple HTTP Server module again on port 80:

anshulp@dzone-vagrant-box:$ python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
172.28.128.1 - - [06/Jul/2017 11:30:13] "GET / HTTP/1.1" 200 -
172.28.128.1 - - [06/Jul/2017 11:30:13] code 404, message File not found
172.28.128.1 - - [06/Jul/2017 11:30:13] "GET /favicon.ico HTTP/1.1" 404 -
172.28.128.1 - - [06/Jul/2017 11:30:13] code 404, message File not found
172.28.128.1 - - [06/Jul/2017 11:30:13] "GET /favicon.ico HTTP/1.1" 404 -

We are now able to serve traffic over privileged port 80 with a non-privileged user.

At the time of writing this article, there are over 40 capabilities which can be assigned per requirement.

There are 3 modes for Capabilities:

  •  e: Effective - This indicates that the capability is "activated."

  •  p: Permitted - This indicates that the capability can be used.

  •  i: Inherited - This indicates that the capability is inherited by child elements/subprocesses.

Capabilities provide a concise and efficient way to assign privileged permissions to non-privileged users.

Topics:
linux ,security ,kernel ,web security

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}