Next Previous Contents

6. LIDS with Capability

Capability is a set of bit to indicate what a process can do. In LIDS, we use capability to limite the capability of all process.

6.1 Capability in kernel.

The capability in kernel is a 32-bit long varient to indicate what the current process can do. The difinition of capability in kernel as following shown.

/* in include/linux/capability.h */

typedef struct __user_cap_header_struct {
        __u32 version;
        int pid;
} *cap_user_header_t;

typedef struct __user_cap_data_struct {
        __u32 effective;
        __u32 permitted;
        __u32 inheritable;
} *cap_user_data_t;

#ifdef __KERNEL__



typedef struct kernel_cap_struct {
        __u32 cap;
} kernel_cap_t;


typedef __u32 kernel_cap_t;


kernel_cap_t cap_bset = CAP_FULL_SET;

Every bit of the kernel_cap_t present a kind of permission(capability). cap_bset is the base of all capability set. It's value can be change by writing to /proc/sys/kernel/cap-bound.

Look at same file as shown above, you will find something like that:


/* in include/linux/capability.h */

/* In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
   overrides the restriction of changing file ownership and group
   ownership. */

#define CAP_CHOWN            0

/* Override all DAC access, including ACL execute access if
   [_POSIX_ACL] is defined. Excluding DAC access covered by

#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. */


You will get what is the exactly meaning of each capability in this file and the LIDS HOWTO written by Boidi.

Each task(process) has three member defined in struct task_struct: cap_effective, cap_inheritable, cap_permitted. We have list a varient cap_bset which indicate a base capability. It check the whole system and determin what kinds of capabilty to control the system.

In most of the system call implementated in kernel, they will call the function capable()( in kernel/sched.c) in the begin of that function. It then call cap_raised() (in include/linux/capability.h) which is shown below,

#define cap_raised(c, flag)  ((cap_t(c) & CAP_TO_MASK(flag)) && ((CAP_TO_MASK(flag) & cap_bset) || (!lids_load) || (!lids_local_load)))
#define cap_raised(c, flag)  (cap_t(c) & CAP_TO_MASK(flag) & cap_bset)

You will see that the cap_bset (it is all "1" by default) is very important here. If we set some bits to 0 in it, the capabilties they present will be disable in the whole system. For example, 18th bit represent CAP_SYS_CHROOT, if we set it to "0", it means that we can not chroot anymore.

If you look at the source code of sys_chroot, you will find that it will check the capability by following,

if (!capable(CAP_SYS_CHROOT)) {
                goto dput_and_out;

The capable() will return 0 for the bit 18 is 0 and then the chroot will return an error to the user.

6.2 Capability in LIDS.

LIDS use capability to restrict the whole process's action. The function used by LIDS is capable(). With many existing capable() in the kernel source, we can disable some capabilities default by the current system and also give some warning when user violate the rules defined by LIDS.

As for the administrator, he can also change the capability by lidsadm and a password. After the kernel authenticate the user, the capability variant cap_bset will be changed.

The most important thing for an administrator is to understand what exactly each capabilitiy means and know what he want on the system. After that, disable the capabilities when sealing the kernel and change them on the fly with a password.

Next Previous Contents