diff options
-rw-r--r-- | CHANGELOG | 10 | ||||
-rw-r--r-- | Make.Rules | 11 | ||||
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | README | 1 | ||||
-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 | ||||
-rw-r--r-- | pam_cap/capability.conf | 2 | ||||
-rw-r--r-- | pgp.keys.asc | 138 | ||||
-rw-r--r-- | progs/capsh.c | 3 | ||||
-rwxr-xr-x | progs/quicktest.sh | 44 | ||||
-rw-r--r-- | progs/setcap.c | 27 |
19 files changed, 316 insertions, 293 deletions
@@ -4,8 +4,14 @@ For release notes and other info pointers: See GIT repository for detailed source history - http://git.kernel.org/?p=libs/libcap/libcap.git;a=summary + https://git.kernel.org/cgit/linux/kernel/git/morgan/libcap.git/ Or simply download the source: - git clone git://git.kernel.org/pub/scm/libs/libcap/libcap.git + git clone git://git.kernel.org/pub/scm/linux/kernel/git/morgan/libcap.git + +The license for this library is here: + + https://git.kernel.org/cgit/linux/kernel/git/morgan/libcap.git/tree/License + +please submit patches compatible with this to morgan at kernel.org. @@ -7,13 +7,13 @@ FAKEROOT=$(DESTDIR) # Autoconf-style prefixes are activated when $(prefix) is defined. -# Otherwise binaries and libraraies are installed in /{lib,sbin}/, +# Otherwise binaries and libraries are installed in /{lib,sbin}/, # header files in /usr/include/ and documentation in /usr/man/man?/. # These choices are motivated by the fact that getcap and setcap are # administrative operations that could be needed to recover a system. ifndef lib -lib=$(shell ldd /usr/bin/ld|fgrep ld-linux|cut -d/ -f2) +lib=$(shell ldd /usr/bin/ld|egrep "ld-linux|ld.so"|cut -d/ -f2) endif ifdef prefix @@ -35,17 +35,18 @@ MANDIR=$(FAKEROOT)$(man_prefix)/man SBINDIR=$(FAKEROOT)$(exec_prefix)/sbin INCDIR=$(FAKEROOT)$(inc_prefix)/include LIBDIR=$(FAKEROOT)$(lib_prefix)/$(lib) +PKGCONFIGDIR=$(FAKEROOT)$(prefix)/$(lib)/pkgconfig # common defines for libcap LIBTITLE=libcap VERSION=2 -MINOR=22 +MINOR=24 # # Compilation specifics -KERNEL_HEADERS := $(topdir)/libcap/include -IPATH += -fPIC -I$(topdir)/libcap/include -I$(KERNEL_HEADERS) +KERNEL_HEADERS := $(topdir)/libcap/include/uapi +IPATH += -fPIC -I$(KERNEL_HEADERS) -I$(topdir)/libcap/include CC := gcc CFLAGS := -O2 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 @@ -27,8 +27,11 @@ distclean: clean $(DISTCLEAN) release: distclean - cd .. && ln -s libcap libcap-$(VERSION).$(MINOR) && tar cvfz libcap-$(VERSION).$(MINOR).tar.gz libcap-$(VERSION).$(MINOR)/* && rm libcap-$(VERSION).$(MINOR) + cd .. && ln -s libcap libcap-$(VERSION).$(MINOR) && tar cvf libcap-$(VERSION).$(MINOR).tar libcap-$(VERSION).$(MINOR)/* && rm libcap-$(VERSION).$(MINOR) + cd .. && gpg -sba -u E2CCF3F4 libcap-$(VERSION).$(MINOR).tar tagrelease: distclean - git tag -s libcap-$(VERSION).$(MINOR) + @echo "sign the tag twice: older DSA key; and newer RSA kernel.org key" + git tag -u D41A6DF2 -s libcap-$(VERSION).$(MINOR) + git tag -u E2CCF3F4 -s libcap-korg-$(VERSION).$(MINOR) make release @@ -20,6 +20,7 @@ More information on capabilities in the Linux kernel can be found at installs the library libcap.XX.Y in /lib[64]/ the binaries in /sbin/ the <sys/capability.h> file in /usr/include + the libcap.pc file in /usr/lib[64]/pkgconfig * for some example programs look in progs. 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} diff --git a/pam_cap/capability.conf b/pam_cap/capability.conf index dd93ea7..09517f8 100644 --- a/pam_cap/capability.conf +++ b/pam_cap/capability.conf @@ -8,7 +8,7 @@ # and thus you'll know about Linux's capability support. # [If you don't know about libcap, the sources for it are here: # -# http://linux.kernel.org/pub/linux/libs/security/linux-privs/ +# http://www.kernel.org/pub/linux/libs/security/linux-privs/ # # .] # diff --git a/pgp.keys.asc b/pgp.keys.asc index 583accd..b39f76a 100644 --- a/pgp.keys.asc +++ b/pgp.keys.asc @@ -1,8 +1,112 @@ +morgan@kernel.org upload/signature key. + +pub 4096R/E2CCF3F4 2011-10-07 Andrew G. Morgan (Work Address) <agm@google.com> +uid Andrew G. Morgan <morgan@kernel.org> +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.15 (GNU/Linux) + +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 +9ifyrw== +=Ibs8 +-----END PGP PUBLIC KEY BLOCK----- pub 1024D/D41A6DF2 2002-09-23 Andrew G. Morgan <morgan@kernel.org> -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.6 (GNU/Linux) -Comment: For info see http://www.gnupg.org +Version: GnuPG v1.4.15 (GNU/Linux) mQGiBD2PVCcRBADmR2dfKJIaGj120v0EjrGbnYic8nKCrDLUHmtiZyIlMeTNqnw/ /Q2m057SIyFC5K5W7XV8LIsOcpEBAdIS5QLClwec/wqVj1FU5TLHNifR9fBq+DaI @@ -13,13 +117,33 @@ mtZnYAkopb8uksBo4yj4abfBZNiVXEttc+XpwhnRODfy576wVy/lmDMTFAz7CYw8 ObE5A/oDWXC35DcgFdmgVH2qr5COEvrDs9T5w4UdRXBMj2khE+32rdP0qqGYCW13 by84+Cpoekmg+6/FqL/At0Xl2a87czur5xR9mrDd32iknws0DggEuf+zL3Twt9kA ftnqgiGr33iaNeXwgqfgQYMbxruLvjaAOayKPhr+tgJU6bIpWbQkQW5kcmV3IEcu -IE1vcmdhbiA8bW9yZ2FuQGtlcm5lbC5vcmc+iFcEExECABcFAj2PVCcFCwcKAwQD -FQMCAxYCAQIXgAAKCRBCF4Sr1Bpt8u+VAJ958HbiLmhrpWjAauN9GrtKudijkACf -R2XasdjQs2ECc2qMX19QwNohDAc= -=7XTB +IE1vcmdhbiA8bW9yZ2FuQGtlcm5lbC5vcmc+iEYEEBECAAYFAj4UuSoACgkQkEgh +GpsoCtOuSACbBUTsx4vlTI5sfutfBntt4TySShoAn1M8hB0S9TkqbG/3OHB8gPm+ +QhjHiEYEERECAAYFAj3irW4ACgkQ1fT/Y8EaOHp+sQCfWWkmmIDvyUi4bA3v4VSw +WaK7mSsAn0N65kYwaW7ohuYJAPeZ6U2HKvFfiEYEExECAAYFAj22Rz8ACgkQi9gu +bzC5S1y0dACfewqmEfYHaTNlCD3PPBCQdWhfi4UAn3+rNDIS5AohUPpbG2/8s9Ef +ZLyKiFcEExECABcFAj2PVCcFCwcKAwQDFQMCAxYCAQIXgAAKCRBCF4Sr1Bpt8u+V +AJ958HbiLmhrpWjAauN9GrtKudijkACfR2XasdjQs2ECc2qMX19QwNohDAeIRgQQ +EQIABgUCQCGDkgAKCRCA8Qy7VNK/WXUIAJ9/Zhn5knqsTTMllzWxe/N1ddGaaACf +SiuBacgyyBdIas15RYaD0YYcNlGJARwEEwECAAYFAj/7MEkACgkQC56ssbtLKadZ +lwgAlS98PQDeITUujwAWpGvOhXh9Bfh27RRKe+MskFTzTzuvmK5+VZGo4suC0PPS +9Hv40UPtt0SvgIuli1Ero0pCP6pWGjgLGPWroXtKfXfYRqnu4vfETt/Ugy2OjG9R +zfum4J8PULD47bsMVw3oMHFucgerArSQNeNx0w5JwYpFJCb5jSf7yXhDCfm+yVv0 +XTls1DC7mtHQrnKGlZe75gEa6zaXRUAYboKbuBifV/anjwMLr2q0JKJSYxFFjIfG +e6QHAuM+NKj3+UAcpkCKYCUobaB315K/pOyKdKfRe5L+8zYQLafNqRlhkvuIkChX +ztyhoXEspp/yIPUJfZFcRldgEohGBBMRAgAGBQJEK0S1AAoJEOCAR9WqTho4asYA +oMdOh1uGDl7qgIO/h5VDwo4Hcs2xAJ4zqSnm0QrNgfFTK9x6j4Jzur+Tl4hGBBMR +AgAGBQJGg9bXAAoJEPmxwkd4G/I7NZ4An2wZ8rfwJt3CSm1ZVPiSf9Ax6J9fAKDM +1PqnD/qIbNMbmURXpEbvWWQunYkBIgQQAQIADAUCRgBA4AUDABJ1AAAKCRCXELib +yletfCcuB/kBeH0/nAFKNw77fNucYhlt9GuT1c1j+8emujF7mwgm18TVcxqRjeSV +PskEkzaX+mzf3Tfn6k7+d/dPYRHPrX0STdsNMqrZkqjt5tiozuLYJUE/PDKafzdI +Q7ya5ps2AdIKNixiSRPC+6cNB85NBorLXs9yg+JkQlPeUI7/DZb2iz1iZXTnyCZv +SvKA7JMYpCOzZ6fWshanZ/91hxQvsYHjYC+zQVTErSYQlBqz8fDLPfyYQiqQFn4c +T/i1WsxYMEaZtexvLuQe9LeaDqyY19DyBaJIIiN6EcGZ4sXRa7M6QUD1HKjEWt62 +U4shHkPGIMgQWLcRZDepovlpGVXLmXEf +=oXom -----END PGP PUBLIC KEY BLOCK----- - The following is my DSA key 'D41A6DF2' signed with my old '2A398175' RSA key. diff --git a/progs/capsh.c b/progs/capsh.c index 52336d7..3ceadcd 100644 --- a/progs/capsh.c +++ b/progs/capsh.c @@ -520,7 +520,8 @@ int main(int argc, char *argv[], char *envp[]) if (set >= 0) { const char *b; b = binary(set); /* use verilog convention for binary string */ - printf("Securebits: 0%o/0x%x/%u'b%s\n", set, set, strlen(b), b); + printf("Securebits: 0%o/0x%x/%u'b%s\n", set, set, + (unsigned) strlen(b), b); printf(" secure-noroot: %s (%s)\n", (set & 1) ? "yes":"no", (set & 2) ? "locked":"unlocked"); diff --git a/progs/quicktest.sh b/progs/quicktest.sh index be3fa7d..ca6bf1e 100755 --- a/progs/quicktest.sh +++ b/progs/quicktest.sh @@ -44,18 +44,23 @@ pass_capsh () { pass_capsh --print -# Make a local non-setuid-0 version of ping -cp /bin/ping . && chmod -s ./ping -# Give it the forced capability it needs -./setcap all=ep ./ping +# Make a local non-setuid-0 version of capsh and call it privileged +cp ./capsh ./privileged && chmod -s ./privileged +if [ $? -ne 0 ]; then + echo "Failed to copy capsh for capability manipulation" + exit 1 +fi + +# Give it the forced capability it could need +./setcap all=ep ./privileged if [ $? -ne 0 ]; then echo "Failed to set all capabilities on file" exit 1 fi -./setcap cap_net_raw=ep ./ping +./setcap cap_setuid,cap_setgid=ep ./privileged if [ $? -ne 0 ]; then - echo "Failed to set single capability on ping file" + echo "Failed to set limited capabilities on privileged file" exit 1 fi @@ -75,37 +80,40 @@ pass_capsh --uid=500 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin # This fails, on 2.6.24, but shouldn't pass_capsh --uid=500 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin=ip\" --uid=500 --forkfor=10 --caps= --print --killit=9 --print" -rm -f tcapsh - # only continue with these if --secbits is supported ./capsh --secbits=0x2f > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "unable to test securebits manipulation - assume not supported (PASS)" - rm -f ./ping + rm -f tcapsh + rm -f privileged exit 0 fi pass_capsh --secbits=42 --print fail_capsh --secbits=32 --keep=1 --keep=0 --print pass_capsh --secbits=10 --keep=0 --keep=1 --print -fail_capsh --secbits=47 -- -c "ping -c1 localhost" +fail_capsh --secbits=47 -- -c "./tcapsh --user=nobody" + +rm -f tcapsh # Suppress uid=0 privilege -fail_capsh --secbits=47 --print -- -c "/bin/ping -c1 localhost" +fail_capsh --secbits=47 --print -- -c "./capsh --user=nobody" -# suppress uid=0 privilege and test this ping -pass_capsh --secbits=0x2f --print -- -c "./ping -c1 localhost" +# suppress uid=0 privilege and test this privileged +pass_capsh --secbits=0x2f --print -- -c "./privileged --user=nobody" # observe that the bounding set can be used to suppress this forced capability -fail_capsh --drop=cap_net_raw,cap_chown --secbits=0x2f --print -- -c "./ping -c1 localhost" +fail_capsh --drop=cap_setuid --secbits=0x2f --print -- -c "./privileged --user=nobody" # change the way the capability is obtained (make it inheritable) -./setcap cap_net_raw=ei ./ping +./setcap cap_setuid,cap_setgid=ei ./privileged -pass_capsh --secbits=47 --inh=cap_net_raw --drop=cap_net_raw \ - --uid=500 --print -- -c "./ping -c1 localhost" +# Note, the bounding set (edited with --drop) only limits p +# capabilities, not i's. +pass_capsh --secbits=47 --inh=cap_setuid,cap_setgid --drop=cap_setuid \ + --uid=500 --print -- -c "./privileged --user=nobody" -rm -f ./ping +rm -f ./privileged # test that we do not support capabilities on setuid shell-scripts cat > hack.sh <<EOF diff --git a/progs/setcap.c b/progs/setcap.c index 0215fc4..83090ae 100644 --- a/progs/setcap.c +++ b/progs/setcap.c @@ -26,7 +26,7 @@ static void usage(void) static int read_caps(int quiet, const char *filename, char *buffer) { - int i=MAXCAP; + int i = MAXCAP; if (!quiet) { fprintf(stderr, "Please enter caps for file [empty line to end]:\n"); @@ -170,10 +170,33 @@ int main(int argc, char **argv) } retval = cap_set_file(*++argv, cap_d); if (retval != 0) { + int explained = 0; +#ifdef linux + cap_value_t cap; + cap_flag_value_t per_state; + + for (cap = 0; + cap_get_flag(cap_d, cap, CAP_PERMITTED, &per_state) != -1; + cap++) { + cap_flag_value_t inh_state, eff_state; + + cap_get_flag(cap_d, cap, CAP_INHERITABLE, &inh_state); + cap_get_flag(cap_d, cap, CAP_EFFECTIVE, &eff_state); + if ((inh_state | per_state) != eff_state) { + fprintf(stderr, "NOTE: Under Linux, effective file capabilities must either be empty, or\n" + " exactly match the union of selected permitted and inheritable bits.\n"); + explained = 1; + break; + } + } +#endif /* def linux */ + fprintf(stderr, "Failed to set capabilities on file `%s' (%s)\n", argv[0], strerror(errno)); - usage(); + if (!explained) { + usage(); + } } } if (cap_d) { |