2.6 C
New York
Friday, February 3, 2023

Understanding Capabilities in Linux System Programming – MUO – MakeUseOf

Capabilities in Linux allow binaries to access certain parts of the system without root privileges. Here’s everything you need to know about them.
Capabilities allow the evaluation of some important system privileges in a separate thread different from the current process. This way, you don't need to run a program as root for it to access certain parts of the system.
As a solution arising from needs, section 25 of POSIX.1e is about this issue. The development of the privileges defined in that section and more has been completed with the release of Linux kernel version 2.6.26. Here's everything you need to know about capabilities in the Linux kernel.
Authorization control in Unix-based systems consists of two steps:
Some applications need to have wider privileges (SUID, SGIT bits) while running. As the most typical example, you can think of the passwd application. With this, users in a system can change their passwords. However, to write to the /etc/shadow file, where the encrypted passwords are kept, it is necessary to work with root user rights (i.e. user ID = 0).
To solve this problem, the passwd application has a SUID bit. Whichever user runs this application, the active owner (EUID) will always be root:
The ability to run SUID applications in the traditional Unix authentication model seems to have solved the problem. However, critical errors in applications with SUID bits open the door to running unwanted codes for users with full authority in the system. An ideal application should be able to run without needing root user rights if possible.
The problem does not end with just the SUID bit. You must also have root user rights when you want to listen on a privileged TCP or UDP port less than 1024 on Unix-based systems. For example, to be able to listen to the TCP 80 port of a web server, you must run the application as the root user.
Over the years, it has been understood how devastating it is to run software that provide service to the network environment with a fully authorized user account. As an interim solution, it was adopted that only a certain and smaller part of the program listens on the privileged port as root, and then changes the active user ID to another user for subsequent processes (for example, the nobody user with restricted rights).
This system, which has been used for years, has worked well with its simplicity and is still used efficiently. However, nowadays, it is possible to get some additional capabilities, specific to the application, via the Linux capabilities API, without the need for root rights, apart from the above-mentioned system.
You can find the most comprehensive implementation of the capabilities API in the Linux kernel. Modern Linux distributions also try to use this new model system-wide as much as possible.
For example, for the ping application to work, it must be able to open RAW sockets, which are generally reserved for root users only. In old Linux distributions, the problem is to give the SUID bit to the application so that normal users can use it. In these versions, when you remove the SUID bit from the application and try to run the application as a normal user, you get the following error:
Whereas on modern Linux distributions, the ping application probably does not have the SUID bit:
Nevertheless, you can run the application successfully as a normal user. The mechanism that makes this possible is that the ping application has the special ability CAP_NET_RAW.
You can learn the additional capabilities of the application with the getcap command as follows:
If the getcap command returns an empty response, you can manually set this value with:
In Linux implementation, the capabilities of each process are grouped under three headings:
The list of permitted, effective, and inheritable capabilities for running processes at any time is displayed as bitmask on the lines CapPrm, CapEff, and CapInh in the file /proc/<PID>/status. In addition, the CapBnd line contains the bitmask used in the capability boundary control operation.
For example, try reading the values of your running shell application from the /proc/self/status file:
The operation of the capability system for files depends on the prerequisite that these properties can be stored in the virtual file system (VFS) layer. Similar to the process model, capabilities for files fall under three headings:
The system determines the permitted capabilities of the process when the corresponding executable runs in this cluster.
Unlike the process capability model, this header stores one bit only: active or inactive. If the bit is active, the capabilities defined in the permitted list of the file are automatically transferred to the effective capability list of the relevant process when this file is run and a process is created. If the bit is not active, the automatic transfer of the permitted capabilities on the file to the running process is not performed.
However, if the code of the relevant application is integrated with the capability system, it can activate the permissions in the permitted set of the file with system calls. The main purpose of this behavior is to ensure that old applications that do not include capability system-specific code, development at the software code level can work with the capability system without the need for any source code changes.
You might think that better-written applications will only use capabilities when needed. If the bit is active, all capabilities in the allowed list become active when the application starts.
As in the process model, the relevant file runs and a process occurs. If another application runs from within the process after that, it is included in the allowed list of the new process. To sum up, it indicates a list of capabilities to inherit.
When you run a certain process as a normal user, you do not have any privileges. As a result, you can only access the partitions that the system allows for normal users. The main reason behind this is to tighten system security and implement such measures.
Allowing all users to access all resources can create a serious security vulnerability. It will be very easy for people who use the system for malicious purposes to exploit system vulnerabilities. Linux capabilities come in handy in such matters. You can easily strengthen the security of your applications with capabilities API powered by the kernel.
Linux capabilities are just one of the issues that need to be thought about to do very powerful methods such as dividing the root user's permissions, assigning various permissions to non-privileged users, and taking various precautions about open ports in internet services with Linux servers.
An engineer and software developer who is a fan of math and technology. He has always liked computers, mathematics and physics. He has developed game engine projects as well as machine learning, artificial neural networks and linear algebra libraries. Moreover continues to work on machine learning and linear matrices.
Join our newsletter for tech tips, reviews, free ebooks, and exclusive deals!


Related Articles


Please enter your comment!
Please enter your name here

Latest Articles