Inheritance of the Linux capability mechanism

Source: Internet
Author: User

Inheritance of the Linux capability mechanism

1. Linux capability mechanism Overview

In previous UNIX systems, to check the permissions of processes, processes are divided into two types: privileged processes (valid user ID is 0) and non-privileged processes (valid user ID is not 0 ). Privileged processes can pass all kernel permission checks, while non-privileged process checks are performed based on the Process Identity (valid ID, valid group, and supplemental group information.

Starting from Linux kernel 2.2, Linux separates the permissions of Super Users for different units and can be enabled and disabled separately, which is called capabilities ). You can assign capabilities to common processes so that they can do what the root user can do.

When the kernel checks whether a process has certain permissions, it does not check whether the process is a privileged process or a non-privileged process, but whether the process has the ability to perform this operation. For example, when a process sets the system time, the kernel checks whether the process has the ability to set the system time (CAP_SYS_TIME), rather than checking whether the process ID is 0;

There are 37 privileges in the current Linux system, which can be viewed in the/usr/include/linux/capability. h file.

2. Implementation of Linux capability mechanism

A complete capability mechanism must meet the following three conditions:

1. For all privileged operations on a process, the Linux kernel must check whether the privileged bit of this operation is enabled for the process.

2. the Linux kernel must provide system calls to allow modification and restoration of process capabilities.

3. The file system must support a capability mechanism that can be attached to an executable file. However, when a file is running, it is attached to the process.

As of Linux kernel 2.6.24, 1 and 2 of the preceding conditions can be met. From Linux kernel 2.6.24, the preceding three conditions can be met

Each process contains three capability sets, which are described as follows:

Permitted: This is a superset of valid capabilities and Inheritable capability. If a process loses a capability in the Permitted set, it cannot obtain the capability again in any way (unless the privileged user gives it again)

Inheritable: indicates the ability of a process to inherit from a new process through execve.

Negative itive: the set of capabilities that the Linux kernel actually checks.

Starting from 2.6.24, the Linux kernel can provide capabilities to executable files. The three sets of capabilities of executable files are as follows:

Permitted: this capability is automatically attached to processes when executable files are executed, ignoring Inhertiable capability.

Inheritable: it performs and operates with the Inheritable set of processes, and decides the Permitted set of the new process after execve is executed.

Inductive tive: the inductive tive of a file is not a set, but a separate bit, used to determine the declarative set of processes.

According to the above description, the capabilities in Linux are divided into two parts: Process Capability and file capability, while the Linux kernel ultimately checks the executive power in process capability. Other parts of the file and process capabilities are used to complete the inheritance and restriction of capabilities.

3. Inheritance of Linux capability mechanism

On the linux terminal, view the capabilities man Manual. The Inheritance formula is as follows:


Copy code
P' (permitted) = (P (inheritable) & F (inheritable) |
(F (permitted) & cap_bset) // permitted of the new process contains the inheritable of the old process and the new process, and the permitted and cap_bset operations of the executable file.
P' (valid) = F (valid )? P' (permitted): 0 // The valid level of the executable file of the new process depends on the valid level of the executable file, enabling: like the new process's permitted, the responsibility is empty
P' (inheritable) = P (inheritable) [I. e., unchanged] // The inheritable of the new process directly inherits the Inheritable of the old process

Note:

P's process capabilities before executing the execve Function
P' process capability after execve function execution
F Executable File capability
The Boundary Value of cap_bset system capability. The default value is 1.

The test procedure is as follows:

Father. c

# Include <stdlib. h>
# Include <stdio. h>
# Include <sys/types. h>
# Include <unistd. h>
# Include <sys/capability. h>
# Include <errno. h>

Void list_capability ()
{
Struct _ user_cap_header_struct cap_header_data;
Cap_user_header_t cap_header = & cap_header_data;

Struct _ user_cap_data_struct cap_data_data;
Cap_user_data_t cap_data = & cap_data_data;

Cap_header-> pid = getpid ();
Cap_header-> version = _ LINUX_CAPABILITY_VERSION_1;

If (capget (cap_header, cap_data) <0 ){
Perror ("Failed capget ");
Exit (1 );
}
Printf ("Cap data permitted: 0x % x, valid tive: 0x % x, inheritable: 0x % x \ n ",
Cap_data-> permitted, cap_data-> valid tive, cap_data-> inheritable );
}

Int main (void)
{
Cap_t caps = cap_init ();
Cap_value_t capList [2] = {CAP_DAC_OVERRIDE, CAP_SYS_TIME };
Unsigned num_caps = 2;
// Cap_set_flag (caps, cap_valid tive, num_caps, capList, CAP_SET );
Cap_set_flag (caps, CAP_INHERITABLE, num_caps, capList, CAP_SET );
Cap_set_flag (caps, CAP_PERMITTED, num_caps, capList, CAP_SET );

If (cap_set_proc (caps ))
{
Perror ("cap_set_proc ");
}

List_capability ();

Execl ("/home/xlzh/code/capability/child", NULL );

Sleep (1000 );
}

Child. c

# Include <stdlib. h>
# Include <stdio. h>
# Include <sys/types. h>
# Include <unistd. h>
# Include <linux/capability. h>
# Include <errno. h>

Void list_capability ()
{
Struct _ user_cap_header_struct cap_header_data;
Cap_user_header_t cap_header = & cap_header_data;

Struct _ user_cap_data_struct cap_data_data;
Cap_user_data_t cap_data = & cap_data_data;

Cap_header-> pid = getpid ();
Cap_header-> version = _ LINUX_CAPABILITY_VERSION_1;

If (capget (cap_header, cap_data) <0 ){
Perror ("Failed capget ");
Exit (1 );
}
Printf ("child Cap data permitted: 0x % x, valid tive: 0x % x, inheritable: 0x % x \ n", cap_data-> permitted, cap_data-> valid tive, cap_data-> inheritable );
}

Int main (void)
{
List_capability ();
Sleep (1000 );
}

Execution Result Analysis

Bkjia @ bkjia :~ /Code/capability $ gcc child. c-o child
Bkjia @ bkjia :~ /Code/capability $ gcc father. c-o father-lcap
Bkjia @ bkjia :~ /Code/capability $ sudo setcap cap_dac_override, cap_sys_time + ei child
Bkjia @ bkjia :~ /Code/capability $ sudo setcap cap_dac_override, cap_sys_time + ip father
/* Run the command separately. The child file has the ability of "E (valid) I (inheritable)". The terminal that executes the child file does not have any capabilities. Apply the formula (cap_bset is set to 1 by default)
* P' (permitted) = (P (inheritable) & F (inheritable) | (F (permitted) & cap_bset) // P' (permitted) = (0x0 & 0x2000002) | (0x0 & all 1), the result is 0
* P' (valid) = F (valid )? P' (permitted): 0 // P' (valid) = 1? P' (permitted): 0, and the result is P' (permitted), that is, 0
* P' (inheritable) = P (inheritable) // P' (inheritable) = 0
* The execution result is as follows:
*/
Bkjia @ bkjia :~ /Code/capability $./child
Child Cap data permitted: 0x0, valid tive: 0x0, inheritable 0x0
/* Run the command separately. The child file has the ability of E (valid) I (inheritable), and the father file that executes the child file has the ability of E (inheritable) and P (permitted). Apply the formula.
* P' (permitted) = (P (inheritable) & F (inheritable) | (F (permitted) & cap_bset) // P' (permitted) = (0x2000002 & 0x2000002) | (0x2000002 & all 1), the result is 0
* P' (valid) = F (valid )? P' (permitted): 0 // P' (valid) = 1? P' (permitted): 0, and the result is P' (permitted), that is, 0x2000002
* P' (inheritable) = P (inheritable) // P' (inheritable) = 0x2000002
* The execution result is as follows:
*/
Bkjia @ bkjia :~ /Code/capability $./father
Father Cap data permitted: 0x2000002, valid tive: 0x0, inheritable: 0x2000002
Child Cap data permitted: 0x2000002, valid tive: 0x2000002, inheritable 0x2000002

The above runs the child executable program separately, and its process is not capable. However, if a father process is used to start and run a child executable program, the process has the corresponding capabilities.

In the above example, both the father and child capabilities are cap_dac_override and cap_sys_time. In fact, the capabilities of the two executable program settings can be different. You can modify the capabilities and apply formulas for calculation.

4. Run the program as the root user

1. Execute the program as the root user, and set P and I of all the capabilities of the process to 1.

2. Run the program as the root user, then the E-enabled process

/* Because the Terminal Process executing the child process does not have the I capability, the inheritable value of all child processes is also 0, and the other capabilities are all 1 */
Bkjia @ bkjia :~ /Code/capability $ sudo./child
Child Cap data permitted: 0 xffffffff, valid tive: 0 xffffffff, inheritable 0x0

5. Impact of changes in process user IDs on capabilities

1. When the valid user ID of a process changes from 0 to not 0, all EIPs can be reset.

2. When the valid user ID of a process changes from non-0 to 0, the existing P set is copied to the E set.

3. If a valid user ID is used for the original real User ID, and the Set User ID is saved as 0, all the P and E capabilities are cleared because these IDs are not 0 in some operations.

4. If the user ID of a file system changes from 0 to not 0, the following capabilities will be cleared in the E set: CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID, CAP_LINUX_IMMUTABLE (since Linux 2.2.30), CAP_MAC_OVERRIDE, CAP_MKNOD. If the user ID of a file system changes from 0 to non-0, the P set's capabilities will be set to the E set.

This article permanently changes the link address:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.