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.
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__
/* #define STRICT_CAP_T_TYPECHE
#ifdef STRICT_CAP_T_TYPECHECKS
typedef struct kernel_cap_struct {
__u32 cap;
} kernel_cap_t;
#else
typedef __u32 kernel_cap_t;
#endif
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
CAP_LINUX_IMMUTABLE. */
#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. */
#define CAP_DAC_READ_SEARCH 2
.........
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,
#ifdef CONFIG_LIDS_ALLOW_SWITCH
#define cap_raised(c, flag) ((cap_t(c) & CAP_TO_MASK(flag)) && ((CAP_TO_MASK(flag) & cap_bset) || (!lids_load) || (!lids_local_load)))
#else
#define cap_raised(c, flag) (cap_t(c) & CAP_TO_MASK(flag) & cap_bset)
#endif
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.
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.