X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=include%2Flinux%2Fcapability.h;h=d567af247ed840271d5f4dfd6c6d5172a5aef74f;hb=c0b004413a46a0a5744e6d2b85220fe9d2c33d48;hp=bb017edffd56816099064f7367f925c15277aa09;hpb=b68680e4731abbd78863063aaa0dca2a6d8cc723;p=safe%2Fjmp%2Flinux-2.6 diff --git a/include/linux/capability.h b/include/linux/capability.h index bb017ed..d567af2 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -14,7 +14,6 @@ #define _LINUX_CAPABILITY_H #include -#include struct task_struct; @@ -23,13 +22,20 @@ struct task_struct; kernel might be somewhat backwards compatible, but don't bet on it. */ -/* XXX - Note, cap_t, is defined by POSIX to be an "opaque" pointer to +/* Note, cap_t, is defined by POSIX (draft) to be an "opaque" pointer to a set of three capability sets. The transposition of 3*the following structure to such a composite is better handled in a user library since the draft standard requires the use of malloc/free etc.. */ -#define _LINUX_CAPABILITY_VERSION 0x19980330 +#define _LINUX_CAPABILITY_VERSION_1 0x19980330 +#define _LINUX_CAPABILITY_U32S_1 1 + +#define _LINUX_CAPABILITY_VERSION_2 0x20071026 /* deprecated - use v3 */ +#define _LINUX_CAPABILITY_U32S_2 2 + +#define _LINUX_CAPABILITY_VERSION_3 0x20080522 +#define _LINUX_CAPABILITY_U32S_3 2 typedef struct __user_cap_header_struct { __u32 version; @@ -42,41 +48,65 @@ typedef struct __user_cap_data_struct { __u32 inheritable; } __user *cap_user_data_t; + #define XATTR_CAPS_SUFFIX "capability" #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX -#define XATTR_CAPS_SZ (3*sizeof(__le32)) #define VFS_CAP_REVISION_MASK 0xFF000000 +#define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK +#define VFS_CAP_FLAGS_EFFECTIVE 0x000001 + #define VFS_CAP_REVISION_1 0x01000000 +#define VFS_CAP_U32_1 1 +#define XATTR_CAPS_SZ_1 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_1)) -#define VFS_CAP_REVISION VFS_CAP_REVISION_1 +#define VFS_CAP_REVISION_2 0x02000000 +#define VFS_CAP_U32_2 2 +#define XATTR_CAPS_SZ_2 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_2)) -#define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK -#define VFS_CAP_FLAGS_EFFECTIVE 0x000001 +#define XATTR_CAPS_SZ XATTR_CAPS_SZ_2 +#define VFS_CAP_U32 VFS_CAP_U32_2 +#define VFS_CAP_REVISION VFS_CAP_REVISION_2 + +#ifdef CONFIG_SECURITY_FILE_CAPABILITIES +extern int file_caps_enabled; +#endif struct vfs_cap_data { - __u32 magic_etc; /* Little endian */ - __u32 permitted; /* Little endian */ - __u32 inheritable; /* Little endian */ + __le32 magic_etc; /* Little endian */ + struct { + __le32 permitted; /* Little endian */ + __le32 inheritable; /* Little endian */ + } data[VFS_CAP_U32]; }; -#ifdef __KERNEL__ +#ifndef __KERNEL__ -/* #define STRICT_CAP_T_TYPECHECKS */ +/* + * Backwardly compatible definition for source code - trapped in a + * 32-bit world. If you find you need this, please consider using + * libcap to untrap yourself... + */ +#define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1 +#define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1 + +#else -#ifdef STRICT_CAP_T_TYPECHECKS +#define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3 +#define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3 typedef struct kernel_cap_struct { - __u32 cap; + __u32 cap[_KERNEL_CAPABILITY_U32S]; } kernel_cap_t; -#else - -typedef __u32 kernel_cap_t; - -#endif +/* exact same as vfs_cap_data but in cpu endian and always filled completely */ +struct cpu_vfs_cap_data { + __u32 magic_etc; + kernel_cap_t permitted; + kernel_cap_t inheritable; +}; -#define _USER_CAP_HEADER_SIZE (2*sizeof(__u32)) +#define _USER_CAP_HEADER_SIZE (sizeof(struct __user_cap_header_struct)) #define _KERNEL_CAP_T_SIZE (sizeof(kernel_cap_t)) #endif @@ -119,10 +149,6 @@ typedef __u32 kernel_cap_t; #define CAP_FSETID 4 -/* Used to decide between falling back on the old suser() or fsuser(). */ - -#define CAP_FS_MASK 0x1f - /* Overrides the restriction that the real or effective user ID of a process sending a signal must match the real or effective user ID of the process receiving the signal. */ @@ -145,8 +171,15 @@ typedef __u32 kernel_cap_t; ** Linux-specific capabilities **/ -/* Transfer any capability in your permitted set to any pid, - remove any capability in your permitted set from any pid */ +/* Without VFS support for capabilities: + * Transfer any capability in your permitted set to any pid, + * remove any capability in your permitted set from any pid + * With VFS support for capabilities (neither of above, but) + * Add any capability from current's capability bounding set + * to the current process' inheritable set + * Allow taking bits out of capability bounding set + * Allow modification of the securebits for a process + */ #define CAP_SETPCAP 8 @@ -195,7 +228,6 @@ typedef __u32 kernel_cap_t; #define CAP_IPC_OWNER 15 /* Insert and remove kernel modules - modify kernel without limit */ -/* Modify cap_bset */ #define CAP_SYS_MODULE 16 /* Allow ioperm/iopl access */ @@ -307,73 +339,200 @@ typedef __u32 kernel_cap_t; #define CAP_SETFCAP 31 +/* Override MAC access. + The base kernel enforces no MAC policy. + An LSM may enforce a MAC policy, and if it does and it chooses + to implement capability based overrides of that policy, this is + the capability it should use to do so. */ + +#define CAP_MAC_OVERRIDE 32 + +/* Allow MAC configuration or state changes. + The base kernel requires no MAC configuration. + An LSM may enforce a MAC policy, and if it does and it chooses + to implement capability based checks on modifications to that + policy or the data required to maintain it, this is the + capability it should use to do so. */ + +#define CAP_MAC_ADMIN 33 + +#define CAP_LAST_CAP CAP_MAC_ADMIN + +#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) + +/* + * Bit location of each capability (used by user-space library and kernel) + */ + +#define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */ +#define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */ + #ifdef __KERNEL__ /* * Internal kernel functions only */ -#ifdef STRICT_CAP_T_TYPECHECKS +#define CAP_FOR_EACH_U32(__capi) \ + for (__capi = 0; __capi < _KERNEL_CAPABILITY_U32S; ++__capi) + +# define CAP_FS_MASK_B0 (CAP_TO_MASK(CAP_CHOWN) \ + | CAP_TO_MASK(CAP_DAC_OVERRIDE) \ + | CAP_TO_MASK(CAP_DAC_READ_SEARCH) \ + | CAP_TO_MASK(CAP_FOWNER) \ + | CAP_TO_MASK(CAP_FSETID)) + +# define CAP_FS_MASK_B1 (CAP_TO_MASK(CAP_MAC_OVERRIDE)) + +#if _KERNEL_CAPABILITY_U32S != 2 +# error Fix up hand-coded capability macro initializers +#else /* HAND-CODED capability initializers */ + +# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) +# define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) +# define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) +# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } }) +# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ + CAP_FS_MASK_B1 } }) + +#endif /* _KERNEL_CAPABILITY_U32S != 2 */ + +#define CAP_INIT_INH_SET CAP_EMPTY_SET + +# define cap_clear(c) do { (c) = __cap_empty_set; } while (0) +# define cap_set_full(c) do { (c) = __cap_full_set; } while (0) +# define cap_set_init_eff(c) do { (c) = __cap_init_eff_set; } while (0) + +#define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) +#define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag)) +#define cap_raised(c, flag) ((c).cap[CAP_TO_INDEX(flag)] & CAP_TO_MASK(flag)) + +#define CAP_BOP_ALL(c, a, b, OP) \ +do { \ + unsigned __capi; \ + CAP_FOR_EACH_U32(__capi) { \ + c.cap[__capi] = a.cap[__capi] OP b.cap[__capi]; \ + } \ +} while (0) + +#define CAP_UOP_ALL(c, a, OP) \ +do { \ + unsigned __capi; \ + CAP_FOR_EACH_U32(__capi) { \ + c.cap[__capi] = OP a.cap[__capi]; \ + } \ +} while (0) + +static inline kernel_cap_t cap_combine(const kernel_cap_t a, + const kernel_cap_t b) +{ + kernel_cap_t dest; + CAP_BOP_ALL(dest, a, b, |); + return dest; +} -#define to_cap_t(x) { x } -#define cap_t(x) (x).cap +static inline kernel_cap_t cap_intersect(const kernel_cap_t a, + const kernel_cap_t b) +{ + kernel_cap_t dest; + CAP_BOP_ALL(dest, a, b, &); + return dest; +} -#else +static inline kernel_cap_t cap_drop(const kernel_cap_t a, + const kernel_cap_t drop) +{ + kernel_cap_t dest; + CAP_BOP_ALL(dest, a, drop, &~); + return dest; +} -#define to_cap_t(x) (x) -#define cap_t(x) (x) +static inline kernel_cap_t cap_invert(const kernel_cap_t c) +{ + kernel_cap_t dest; + CAP_UOP_ALL(dest, c, ~); + return dest; +} -#endif +static inline int cap_isclear(const kernel_cap_t a) +{ + unsigned __capi; + CAP_FOR_EACH_U32(__capi) { + if (a.cap[__capi] != 0) + return 0; + } + return 1; +} + +/* + * Check if "a" is a subset of "set". + * return 1 if ALL of the capabilities in "a" are also in "set" + * cap_issubset(0101, 1111) will return 1 + * return 0 if ANY of the capabilities in "a" are not in "set" + * cap_issubset(1111, 0101) will return 0 + */ +static inline int cap_issubset(const kernel_cap_t a, const kernel_cap_t set) +{ + kernel_cap_t dest; + dest = cap_drop(a, set); + return cap_isclear(dest); +} -#define CAP_EMPTY_SET to_cap_t(0) -#define CAP_FULL_SET to_cap_t(~0) -#define CAP_INIT_EFF_SET to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP)) -#define CAP_INIT_INH_SET to_cap_t(0) +/* Used to decide between falling back on the old suser() or fsuser(). */ -#define CAP_TO_MASK(x) (1 << (x)) -#define cap_raise(c, flag) (cap_t(c) |= CAP_TO_MASK(flag)) -#define cap_lower(c, flag) (cap_t(c) &= ~CAP_TO_MASK(flag)) -#define cap_raised(c, flag) (cap_t(c) & CAP_TO_MASK(flag)) +static inline int cap_is_fs_cap(int cap) +{ + const kernel_cap_t __cap_fs_set = CAP_FS_SET; + return !!(CAP_TO_MASK(cap) & __cap_fs_set.cap[CAP_TO_INDEX(cap)]); +} -static inline kernel_cap_t cap_combine(kernel_cap_t a, kernel_cap_t b) +static inline kernel_cap_t cap_drop_fs_set(const kernel_cap_t a) { - kernel_cap_t dest; - cap_t(dest) = cap_t(a) | cap_t(b); - return dest; + const kernel_cap_t __cap_fs_set = CAP_FS_SET; + return cap_drop(a, __cap_fs_set); } -static inline kernel_cap_t cap_intersect(kernel_cap_t a, kernel_cap_t b) +static inline kernel_cap_t cap_raise_fs_set(const kernel_cap_t a, + const kernel_cap_t permitted) { - kernel_cap_t dest; - cap_t(dest) = cap_t(a) & cap_t(b); - return dest; + const kernel_cap_t __cap_fs_set = CAP_FS_SET; + return cap_combine(a, + cap_intersect(permitted, __cap_fs_set)); } -static inline kernel_cap_t cap_drop(kernel_cap_t a, kernel_cap_t drop) +static inline kernel_cap_t cap_drop_nfsd_set(const kernel_cap_t a) { - kernel_cap_t dest; - cap_t(dest) = cap_t(a) & ~cap_t(drop); - return dest; + const kernel_cap_t __cap_fs_set = CAP_NFSD_SET; + return cap_drop(a, __cap_fs_set); } -static inline kernel_cap_t cap_invert(kernel_cap_t c) +static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a, + const kernel_cap_t permitted) { - kernel_cap_t dest; - cap_t(dest) = ~cap_t(c); - return dest; + const kernel_cap_t __cap_nfsd_set = CAP_NFSD_SET; + return cap_combine(a, + cap_intersect(permitted, __cap_nfsd_set)); } -#define cap_isclear(c) (!cap_t(c)) -#define cap_issubset(a,set) (!(cap_t(a) & ~cap_t(set))) +extern const kernel_cap_t __cap_empty_set; +extern const kernel_cap_t __cap_full_set; +extern const kernel_cap_t __cap_init_eff_set; -#define cap_clear(c) do { cap_t(c) = 0; } while(0) -#define cap_set_full(c) do { cap_t(c) = ~0; } while(0) -#define cap_mask(c,mask) do { cap_t(c) &= cap_t(mask); } while(0) +kernel_cap_t cap_set_effective(const kernel_cap_t pE_new); -#define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK) +/** + * has_capability - Determine if a task has a superior capability available + * @t: The task in question + * @cap: The capability to be tested for + * + * Return true if the specified task has the given superior capability + * currently in effect, false if not. + * + * Note that this does not set PF_SUPERPRIV on the task. + */ +#define has_capability(t, cap) (security_capable((t), (cap)) == 0) -int capable(int cap); -int __capable(struct task_struct *t, int cap); +extern int capable(int cap); #endif /* __KERNEL__ */