diff options
Diffstat (limited to 'libcap')
-rw-r--r-- | libcap/Makefile | 16 | ||||
-rw-r--r-- | libcap/cap_alloc.c | 2 | ||||
-rw-r--r-- | libcap/cap_extint.c | 10 | ||||
-rw-r--r-- | libcap/cap_file.c | 4 | ||||
-rw-r--r-- | libcap/include/sys/capability.h | 4 | ||||
-rw-r--r-- | libcap/include/uapi/linux/capability.h (renamed from libcap/include/linux/capability.h) | 250 | ||||
-rw-r--r-- | libcap/include/uapi/linux/prctl.h (renamed from libcap/include/linux/prctl.h) | 47 | ||||
-rw-r--r-- | libcap/include/uapi/linux/securebits.h (renamed from libcap/include/linux/securebits.h) | 9 | ||||
-rw-r--r-- | libcap/libcap.h | 13 | ||||
-rw-r--r-- | libcap/libcap.pc.in | 11 |
10 files changed, 111 insertions, 255 deletions
diff --git a/libcap/Makefile b/libcap/Makefile index 4762c60..20ab00f 100644 --- a/libcap/Makefile +++ b/libcap/Makefile @@ -17,6 +17,7 @@ FILES=cap_alloc cap_proc cap_extint cap_flag cap_text ifeq ($(LIBATTR),yes) FILES += cap_file LDFLAGS += -lattr +DEPS = -lattr endif INCLS=libcap.h cap_names.h $(INCS) @@ -25,13 +26,22 @@ MAJLIBNAME=$(LIBNAME).$(VERSION) MINLIBNAME=$(MAJLIBNAME).$(MINOR) GPERF_OUTPUT = _caps_output.gperf -all: $(MINLIBNAME) $(STALIBNAME) +all: $(MINLIBNAME) $(STALIBNAME) libcap.pc ifeq ($(shell gperf --version > /dev/null 2>&1 && echo yes),yes) USE_GPERF_OUTPUT = $(GPERF_OUTPUT) INCLUDE_GPERF_OUTPUT = -include $(GPERF_OUTPUT) endif +libcap.pc: libcap.pc.in + sed -e 's,@prefix@,$(prefix),' \ + -e 's,@exec_prefix@,$(exec_prefix),' \ + -e 's,@libdir@,$(lib_prefix)/$(lib),' \ + -e 's,@includedir@,$(inc_prefix)/include,' \ + -e 's,@VERSION@,$(VERSION).$(MINOR),' \ + -e 's,@deps@,$(DEPS),' \ + $< >$@ + _makenames: _makenames.c cap_names.list.h $(BUILD_CC) $(BUILD_CFLAGS) $< -o $@ @@ -71,9 +81,11 @@ install: all ifeq ($(FAKEROOT),) -/sbin/ldconfig endif + mkdir -p -m 0755 $(PKGCONFIGDIR) + install -m 0644 libcap.pc $(PKGCONFIGDIR)/libcap.pc clean: $(LOCALCLEAN) - rm -f $(OBJS) $(LIBNAME)* $(STALIBNAME) + rm -f $(OBJS) $(LIBNAME)* $(STALIBNAME) libcap.pc rm -f cap_names.h cap_names.list.h _makenames $(GPERF_OUTPUT) cd include/sys && $(LOCALCLEAN) diff --git a/libcap/cap_alloc.c b/libcap/cap_alloc.c index 5fa5e93..525ea90 100644 --- a/libcap/cap_alloc.c +++ b/libcap/cap_alloc.c @@ -125,7 +125,7 @@ int cap_free(void *data_p) } if ( good_cap_string(data_p) ) { - int length = strlen(data_p) + sizeof(__u32); + size_t length = strlen(data_p) + sizeof(__u32); data_p = -1 + (__u32 *) data_p; memset(data_p, 0, length); free(data_p); diff --git a/libcap/cap_extint.c b/libcap/cap_extint.c index 5a0cc8e..7d6e7ad 100644 --- a/libcap/cap_extint.c +++ b/libcap/cap_extint.c @@ -31,7 +31,7 @@ struct cap_ext_struct { ssize_t cap_size(cap_t caps) { - return sizeof(struct cap_ext_struct); + return ssizeof(struct cap_ext_struct); } /* @@ -46,7 +46,7 @@ ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length) int i; /* valid arguments? */ - if (!good_cap_t(cap_d) || length < sizeof(struct cap_ext_struct) + if (!good_cap_t(cap_d) || length < ssizeof(struct cap_ext_struct) || cap_ext == NULL) { errno = EINVAL; return -1; @@ -57,7 +57,7 @@ ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length) result->length_of_capset = CAP_SET_SIZE; for (i=0; i<NUMBER_OF_CAP_SETS; ++i) { - int j; + size_t j; for (j=0; j<CAP_SET_SIZE; ) { __u32 val; @@ -71,7 +71,7 @@ ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length) } /* All done: return length of external representation */ - return (sizeof(struct cap_ext_struct)); + return (ssizeof(struct cap_ext_struct)); } /* @@ -99,7 +99,7 @@ cap_t cap_copy_int(const void *cap_ext) blen = export->length_of_capset; for (set=0; set<NUMBER_OF_CAP_SETS; ++set) { - int blk; + unsigned blk; int bno = 0; for (blk=0; blk<(CAP_SET_SIZE/sizeof(__u32)); ++blk) { __u32 val = 0; diff --git a/libcap/cap_file.c b/libcap/cap_file.c index 634e601..d3dc1d0 100644 --- a/libcap/cap_file.c +++ b/libcap/cap_file.c @@ -187,7 +187,7 @@ cap_t cap_get_fd(int fildes) /* fill the capability sets via a system call */ sizeofcaps = fgetxattr(fildes, XATTR_NAME_CAPS, &rawvfscap, sizeof(rawvfscap)); - if (sizeofcaps < sizeof(rawvfscap.magic_etc)) { + if (sizeofcaps < ssizeof(rawvfscap.magic_etc)) { cap_free(result); result = NULL; } else { @@ -217,7 +217,7 @@ cap_t cap_get_file(const char *filename) /* fill the capability sets via a system call */ sizeofcaps = getxattr(filename, XATTR_NAME_CAPS, &rawvfscap, sizeof(rawvfscap)); - if (sizeofcaps < sizeof(rawvfscap.magic_etc)) { + if (sizeofcaps < ssizeof(rawvfscap.magic_etc)) { cap_free(result); result = NULL; } else { diff --git a/libcap/include/sys/capability.h b/libcap/include/sys/capability.h index 4b54acc..64ac50e 100644 --- a/libcap/include/sys/capability.h +++ b/libcap/include/sys/capability.h @@ -23,13 +23,11 @@ extern "C" { #include <stdint.h> #include <linux/types.h> -/* - * Required to limit what gets defined in the kernel header file. - */ #ifndef __user #define __user #endif #include <linux/capability.h> +#include <linux/xattr.h> /* * POSIX capability types diff --git a/libcap/include/linux/capability.h b/libcap/include/uapi/linux/capability.h index 4924f2a..a4b907f 100644 --- a/libcap/include/linux/capability.h +++ b/libcap/include/uapi/linux/capability.h @@ -7,11 +7,11 @@ * * See here for the libcap library ("POSIX draft" compliance): * - * ftp://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/ + * http://www.kernel.org/pub/linux/libs/security/linux-privs/ */ -#ifndef _LINUX_CAPABILITY_H -#define _LINUX_CAPABILITY_H +#ifndef _UAPI_LINUX_CAPABILITY_H +#define _UAPI_LINUX_CAPABILITY_H #include <linux/types.h> @@ -49,9 +49,6 @@ typedef struct __user_cap_data_struct { } __user *cap_user_data_t; -#define XATTR_CAPS_SUFFIX "capability" -#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX - #define VFS_CAP_REVISION_MASK 0xFF000000 #define VFS_CAP_REVISION_SHIFT 24 #define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK @@ -87,27 +84,6 @@ struct vfs_cap_data { #define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1 #define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1 -#else - -#define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3 -#define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3 - -extern int file_caps_enabled; - -typedef struct kernel_cap_struct { - __u32 cap[_KERNEL_CAPABILITY_U32S]; -} kernel_cap_t; - -/* 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 (sizeof(struct __user_cap_header_struct)) -#define _KERNEL_CAP_T_SIZE (sizeof(kernel_cap_t)) - #endif @@ -201,7 +177,7 @@ struct cpu_vfs_cap_data { /* Allow modification of routing tables */ /* Allow setting arbitrary process / process group ownership on sockets */ -/* Allow binding to any address for transparent proxying */ +/* Allow binding to any address for transparent proxying (also via NET_RAW) */ /* Allow setting TOS (type of service) */ /* Allow setting promiscuous mode */ /* Allow clearing driver statistics */ @@ -213,6 +189,7 @@ struct cpu_vfs_cap_data { /* Allow use of RAW sockets */ /* Allow use of PACKET sockets */ +/* Allow binding to any address for transparent proxying (also via NET_ADMIN) */ #define CAP_NET_RAW 13 @@ -249,7 +226,6 @@ struct cpu_vfs_cap_data { /* Allow configuration of the secure attention key */ /* Allow administration of the random device */ /* Allow examination and configuration of disk quotas */ -/* Allow configuring the kernel's syslog (printk behaviour) */ /* Allow setting the domainname */ /* Allow setting the hostname */ /* Allow calling bdflush() */ @@ -355,222 +331,28 @@ struct cpu_vfs_cap_data { #define CAP_MAC_ADMIN 33 +/* Allow configuring the kernel's syslog (printk behaviour) */ -/* Privileged syslog operations currently require CAP_SYSLOG. - CAP_SYS_ADMIN is not acceptable anymore. */ #define CAP_SYSLOG 34 -#define CAP_LAST_CAP CAP_SYSLOG +/* Allow triggering something that will wake the system */ -#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) +#define CAP_WAKE_ALARM 35 -/* - * 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 */ +/* Allow preventing system suspends */ -#ifdef __KERNEL__ +#define CAP_BLOCK_SUSPEND 36 -/* - * Internal kernel functions only - */ +#define CAP_LAST_CAP CAP_BLOCK_SUSPEND -#define CAP_FOR_EACH_U32(__capi) \ - for (__capi = 0; __capi < _KERNEL_CAPABILITY_U32S; ++__capi) - -/* - * CAP_FS_MASK and CAP_NFSD_MASKS: - * - * The fs mask is all the privileges that fsuid==0 historically meant. - * At one time in the past, that included CAP_MKNOD and CAP_LINUX_IMMUTABLE. - * - * It has never meant setting security.* and trusted.* xattrs. - * - * We could also define fsmask as follows: - * 1. CAP_FS_MASK is the privilege to bypass all fs-related DAC permissions - * 2. The security.* and trusted.* xattrs are fs-related MAC permissions - */ - -# define CAP_FS_MASK_B0 (CAP_TO_MASK(CAP_CHOWN) \ - | CAP_TO_MASK(CAP_MKNOD) \ - | 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_TO_MASK(CAP_LINUX_IMMUTABLE), \ - 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; -} - -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; -} - -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; -} - -static inline kernel_cap_t cap_invert(const kernel_cap_t c) -{ - kernel_cap_t dest; - CAP_UOP_ALL(dest, c, ~); - return dest; -} - -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; -} +#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) /* - * 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); -} - -/* Used to decide between falling back on the old suser() or fsuser(). */ - -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_drop_fs_set(const kernel_cap_t a) -{ - const kernel_cap_t __cap_fs_set = CAP_FS_SET; - return cap_drop(a, __cap_fs_set); -} - -static inline kernel_cap_t cap_raise_fs_set(const kernel_cap_t a, - const kernel_cap_t permitted) -{ - 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_nfsd_set(const kernel_cap_t a) -{ - const kernel_cap_t __cap_fs_set = CAP_NFSD_SET; - return cap_drop(a, __cap_fs_set); -} - -static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a, - const kernel_cap_t permitted) -{ - const kernel_cap_t __cap_nfsd_set = CAP_NFSD_SET; - return cap_combine(a, - cap_intersect(permitted, __cap_nfsd_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; - -/** - * 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_real_capable((t), (cap)) == 0) - -/** - * has_capability_noaudit - Determine if a task has a superior capability available (unaudited) - * @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, but don't write an audit message for the - * check. - * - * Note that this does not set PF_SUPERPRIV on the task. + * Bit location of each capability (used by user-space library and kernel) */ -#define has_capability_noaudit(t, cap) \ - (security_real_capable_noaudit((t), (cap)) == 0) - -extern int capable(int cap); -/* audit system wants to get cap info from files as well */ -struct dentry; -extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); +#define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */ +#define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */ -#endif /* __KERNEL__ */ -#endif /* !_LINUX_CAPABILITY_H */ +#endif /* _UAPI_LINUX_CAPABILITY_H */ diff --git a/libcap/include/linux/prctl.h b/libcap/include/uapi/linux/prctl.h index a3baeb2..289760f 100644 --- a/libcap/include/linux/prctl.h +++ b/libcap/include/uapi/linux/prctl.h @@ -102,4 +102,51 @@ #define PR_MCE_KILL_GET 34 +/* + * Tune up process memory map specifics. + */ +#define PR_SET_MM 35 +# define PR_SET_MM_START_CODE 1 +# define PR_SET_MM_END_CODE 2 +# define PR_SET_MM_START_DATA 3 +# define PR_SET_MM_END_DATA 4 +# define PR_SET_MM_START_STACK 5 +# define PR_SET_MM_START_BRK 6 +# define PR_SET_MM_BRK 7 +# define PR_SET_MM_ARG_START 8 +# define PR_SET_MM_ARG_END 9 +# define PR_SET_MM_ENV_START 10 +# define PR_SET_MM_ENV_END 11 +# define PR_SET_MM_AUXV 12 +# define PR_SET_MM_EXE_FILE 13 + +/* + * Set specific pid that is allowed to ptrace the current task. + * A value of 0 mean "no process". + */ +#define PR_SET_PTRACER 0x59616d61 +# define PR_SET_PTRACER_ANY ((unsigned long)-1) + +#define PR_SET_CHILD_SUBREAPER 36 +#define PR_GET_CHILD_SUBREAPER 37 + +/* + * If no_new_privs is set, then operations that grant new privileges (i.e. + * execve) will either fail or not grant them. This affects suid/sgid, + * file capabilities, and LSMs. + * + * Operations that merely manipulate or drop existing privileges (setresuid, + * capset, etc.) will still work. Drop those privileges if you want them gone. + * + * Changing LSM security domain is considered a new privilege. So, for example, + * asking selinux for a specific new context (e.g. with runcon) will result + * in execve returning -EPERM. + * + * See Documentation/prctl/no_new_privs.txt for more details. + */ +#define PR_SET_NO_NEW_PRIVS 38 +#define PR_GET_NO_NEW_PRIVS 39 + +#define PR_GET_TID_ADDRESS 40 + #endif /* _LINUX_PRCTL_H */ diff --git a/libcap/include/linux/securebits.h b/libcap/include/uapi/linux/securebits.h index 3340617..985aac9 100644 --- a/libcap/include/linux/securebits.h +++ b/libcap/include/uapi/linux/securebits.h @@ -1,14 +1,11 @@ -#ifndef _LINUX_SECUREBITS_H -#define _LINUX_SECUREBITS_H 1 +#ifndef _UAPI_LINUX_SECUREBITS_H +#define _UAPI_LINUX_SECUREBITS_H /* Each securesetting is implemented using two bits. One bit specifies whether the setting is on or off. The other bit specify whether the setting is locked or not. A setting which is locked cannot be changed from user-level. */ #define issecure_mask(X) (1 << (X)) -#ifdef __KERNEL__ -#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits)) -#endif #define SECUREBITS_DEFAULT 0x00000000 @@ -51,4 +48,4 @@ issecure_mask(SECURE_KEEP_CAPS)) #define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) -#endif /* !_LINUX_SECUREBITS_H */ +#endif /* _UAPI_LINUX_SECUREBITS_H */ diff --git a/libcap/libcap.h b/libcap/libcap.h index 1e66f98..2596c11 100644 --- a/libcap/libcap.h +++ b/libcap/libcap.h @@ -12,14 +12,15 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdint.h> #include <sys/capability.h> #ifndef __u8 -#define __u8 unsigned char +#define __u8 uint8_t #endif /* __8 */ #ifndef __u32 -#define __u32 unsigned int +#define __u32 uint32_t #endif /* __u32 */ /* include the names for the caps and a definition of __CAP_BITS */ @@ -197,4 +198,12 @@ extern int capsetp(pid_t pid, cap_t cap_d); #define PR_GET_SECUREBITS 27 #define PR_SET_SECUREBITS 28 +/* + * The library compares sizeof() with integer return values. To avoid + * signed/unsigned comparisons, leading to unfortunate + * misinterpretations of -1, we provide a convenient cast-to-signed-integer + * version of sizeof(). + */ +#define ssizeof(x) ((ssize_t) sizeof(x)) + #endif /* LIBCAP_H */ diff --git a/libcap/libcap.pc.in b/libcap/libcap.pc.in new file mode 100644 index 0000000..a28e3e4 --- /dev/null +++ b/libcap/libcap.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libcap +Description: libcap +Version: @VERSION@ +Libs: -L${libdir} -lcap +Libs.private: @deps@ +Cflags: -I${includedir} |