aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Lucangeli Obes <jorgelo@google.com>2016-11-10 22:12:48 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-11-10 22:12:48 +0000
commit0a972d8f9984f519ae05bea92ad1ad34b9485921 (patch)
treebb1f11259d81b794c3f5d0dcdfc7aff04e35d936
parentc590c72c39c09c5bde7d22c75f4062aedc761ac8 (diff)
parentb562e4e37c8b0bca6789f05da1f5ac508cc08a97 (diff)
downloadlibcap-0a972d8f9984f519ae05bea92ad1ad34b9485921.tar.gz
Update our copy of libcap. am: 02403a9504
am: b562e4e37c Change-Id: Id47b57b6a81377d40b80d88da1b5b56fa5fe5cd1
-rw-r--r--.gitignore1
-rw-r--r--Make.Rules5
-rw-r--r--Makefile3
-rw-r--r--kdebug/Makefile14
-rw-r--r--kdebug/test-bash.sh4
-rw-r--r--kdebug/test-init.sh14
-rwxr-xr-xkdebug/test-kernel.sh67
-rw-r--r--kdebug/test-passwd2
-rw-r--r--kdebug/test-prompt.sh2
-rw-r--r--libcap/Makefile10
-rw-r--r--libcap/cap_file.c17
-rw-r--r--libcap/include/uapi/linux/capability.h11
-rw-r--r--libcap/include/uapi/linux/securebits.h11
-rw-r--r--progs/Makefile5
-rwxr-xr-xprogs/quicktest.sh19
-rw-r--r--progs/setcap.c3
16 files changed, 157 insertions, 31 deletions
diff --git a/.gitignore b/.gitignore
index a70237a..1971ad5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
+patches/
*.o
*~
diff --git a/Make.Rules b/Make.Rules
index 18b7cf7..8347b26 100644
--- a/Make.Rules
+++ b/Make.Rules
@@ -40,7 +40,7 @@ PKGCONFIGDIR=$(prefix)/$(lib)/pkgconfig
# common defines for libcap
LIBTITLE=libcap
VERSION=2
-MINOR=24
+MINOR=25
#
# Compilation specifics
@@ -70,7 +70,6 @@ CFLAGS += -Dlinux $(WARNINGS) $(DEBUG)
PAM_CAP := $(shell if [ -f /usr/include/security/pam_modules.h ]; then echo yes ; else echo no ; fi)
INDENT := $(shell if [ -n "$$(which indent 2>/dev/null)" ]; then echo "| indent -kr" ; fi)
DYNAMIC := $(shell if [ ! -d "$(topdir)/.git" ]; then echo yes; fi)
-LIBATTR := yes
# When installing setcap, set its inheritable bit to be able to place
# capabilities on files. It can be used in conjunction with pam_cap
@@ -80,7 +79,7 @@ LIBATTR := yes
#
# make RAISE_SETFCAP=no install
#
-RAISE_SETFCAP := $(LIBATTR)
+RAISE_SETFCAP := yes
# Global cleanup stuff
diff --git a/Makefile b/Makefile
index 124d10d..ad58c3a 100644
--- a/Makefile
+++ b/Makefile
@@ -8,13 +8,14 @@ include Make.Rules
# flags
#
-all install clean: %: %-here
+all install clean kdebug: %: %-here
$(MAKE) -C libcap $@
ifneq ($(PAM_CAP),no)
$(MAKE) -C pam_cap $@
endif
$(MAKE) -C progs $@
$(MAKE) -C doc $@
+ $(MAKE) -C kdebug $@
all-here:
diff --git a/kdebug/Makefile b/kdebug/Makefile
new file mode 100644
index 0000000..c710050
--- /dev/null
+++ b/kdebug/Makefile
@@ -0,0 +1,14 @@
+topdir=$(shell pwd)/..
+include ../Make.Rules
+
+test:
+ ./test-kernel.sh
+
+all:
+ @echo cd to kdebug to test a kernel build
+
+install:
+
+clean:
+ $(LOCALCLEAN)
+ rm -f fs.conf initramfs.img
diff --git a/kdebug/test-bash.sh b/kdebug/test-bash.sh
new file mode 100644
index 0000000..2777b21
--- /dev/null
+++ b/kdebug/test-bash.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# bash is used in various headers so we need a wrapper to invoke sh
+# instead.
+exec sh "$@"
diff --git a/kdebug/test-init.sh b/kdebug/test-init.sh
new file mode 100644
index 0000000..4b55b51
--- /dev/null
+++ b/kdebug/test-init.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+PATH=/bin
+
+echo -n "Mounting filesystems ... "
+mount -t proc proc /proc
+mount -t devtmpfs dev /dev
+mount -t sysfs sys /sys
+mount -t devpts pts /dev/pts
+echo done
+
+echo Hello, World
+cd /root
+./quicktest.sh
+sh -i
diff --git a/kdebug/test-kernel.sh b/kdebug/test-kernel.sh
new file mode 100755
index 0000000..c8ce144
--- /dev/null
+++ b/kdebug/test-kernel.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# The following is a synthesis of info in:
+#
+# http://vmsplice.net/~stefan/stefanha-kernel-recipes-2015.pdf
+# http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/README
+#
+KBASE=../../linux
+#APPEND="console=ttyS0"
+
+function die {
+ echo "$*"
+ exit 1
+}
+
+pushd ..
+make || die "failed to make libcap tree"
+popd
+
+# Assumes desired make *config (eg. make defconfig) is already done.
+pushd $KBASE
+pwd
+make V=1 all || die "failed to build kernel: $0"
+popd
+
+HERE=$(/bin/pwd)
+
+cat > fs.conf <<EOF
+file /init test-init.sh 0755 0 0
+dir /etc 0755 0 0
+file /etc/passwd test-passwd 0444 0 0
+dir /lib 0755 0 0
+dir /proc 0755 0 0
+dir /dev 0755 0 0
+dir /sys 0755 0 0
+dir /sbin 0755 0 0
+file /sbin/busybox /usr/sbin/busybox 0755 0 0
+dir /bin 0755 0 0
+file /bin/myprompt test-prompt.sh 0755 0 0
+file /bin/bash test-bash.sh 0755 0 0
+dir /usr 0755 0 0
+dir /usr/bin 0755 0 0
+dir /root 0755 0 0
+file /root/quicktest.sh $HERE/../progs/quicktest.sh 0755 0 0
+file /root/setcap $HERE/../progs/setcap 0755 0 0
+file /root/getcap $HERE/../progs/getcap 0755 0 0
+file /root/capsh $HERE/../progs/capsh 0755 0 0
+file /root/getpcaps $HERE/../progs/getpcaps 0755 0 0
+EOF
+
+COMMANDS="ls ln cp id pwd mkdir rmdir cat rm sh mount umount chmod less"
+for f in $COMMANDS; do
+ echo slink /bin/$f /sbin/busybox 0755 0 0 >> fs.conf
+done
+
+UCOMMANDS="id cut"
+for f in $UCOMMANDS; do
+ echo slink /usr/bin/$f /sbin/busybox 0755 0 0 >> fs.conf
+done
+
+$KBASE/usr/gen_init_cpio fs.conf | gzip -9 > initramfs.img
+
+KERNEL=$KBASE/arch/x86_64/boot/bzImage
+
+qemu-system-$(uname -m) -m 1024 \
+ -kernel $KERNEL \
+ -initrd initramfs.img \
+ -append "$APPEND"
diff --git a/kdebug/test-passwd b/kdebug/test-passwd
new file mode 100644
index 0000000..4fa92a4
--- /dev/null
+++ b/kdebug/test-passwd
@@ -0,0 +1,2 @@
+root:x:0:0:root:/root:/bin/bash
+nobody:x:99:99:Nobody:/:/sbin/nologin
diff --git a/kdebug/test-prompt.sh b/kdebug/test-prompt.sh
new file mode 100644
index 0000000..1c19c16
--- /dev/null
+++ b/kdebug/test-prompt.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo -n "$(pwd)# "
diff --git a/libcap/Makefile b/libcap/Makefile
index 0ccd2e7..d189777 100644
--- a/libcap/Makefile
+++ b/libcap/Makefile
@@ -10,15 +10,7 @@ LIBNAME=$(LIBTITLE).so
STALIBNAME=$(LIBTITLE).a
#
-FILES=cap_alloc cap_proc cap_extint cap_flag cap_text
-
-# make including file support something you can override (no libattr
-# no support).
-ifeq ($(LIBATTR),yes)
-FILES += cap_file
-LDFLAGS += -lattr
-DEPS = -lattr
-endif
+FILES=cap_alloc cap_proc cap_extint cap_flag cap_text cap_file
INCLS=libcap.h cap_names.h $(INCS)
OBJS=$(addsuffix .o, $(FILES))
diff --git a/libcap/cap_file.c b/libcap/cap_file.c
index 553c2d2..76aac8c 100644
--- a/libcap/cap_file.c
+++ b/libcap/cap_file.c
@@ -1,18 +1,27 @@
/*
- * Copyright (c) 1997,2007 Andrew G Morgan <morgan@kernel.org>
+ * Copyright (c) 1997,2007,2016 Andrew G Morgan <morgan@kernel.org>
*
* This file deals with setting capabilities on files.
*/
#include <sys/types.h>
-#include <sys/xattr.h>
#include <byteswap.h>
#include <sys/stat.h>
#include <unistd.h>
-
#include <linux/xattr.h>
-#define XATTR_SECURITY_PREFIX "security."
+/*
+ * We hardcode the prototypes for the Linux system calls here since
+ * there are no libcap library APIs that expose the user to these
+ * details, and that way we don't need to force clients to link any
+ * other libraries to access them.
+ */
+extern ssize_t getxattr(const char *, const char *, void *, size_t);
+extern ssize_t fgetxattr(int, const char *, void *, size_t);
+extern int setxattr(const char *, const char *, const void *, size_t, int);
+extern int fsetxattr(int, const char *, const void *, size_t, int);
+extern int removexattr(const char *, const char *);
+extern int fremovexattr(int, const char *);
#include "libcap.h"
diff --git a/libcap/include/uapi/linux/capability.h b/libcap/include/uapi/linux/capability.h
index a4b907f..432e023 100644
--- a/libcap/include/uapi/linux/capability.h
+++ b/libcap/include/uapi/linux/capability.h
@@ -308,8 +308,12 @@ struct vfs_cap_data {
#define CAP_LEASE 28
+/* Allow writing the audit log via unicast netlink socket */
+
#define CAP_AUDIT_WRITE 29
+/* Allow configuration of audit via unicast netlink socket */
+
#define CAP_AUDIT_CONTROL 30
#define CAP_SETFCAP 31
@@ -343,7 +347,12 @@ struct vfs_cap_data {
#define CAP_BLOCK_SUSPEND 36
-#define CAP_LAST_CAP CAP_BLOCK_SUSPEND
+/* Allow reading the audit log via multicast netlink socket */
+
+#define CAP_AUDIT_READ 37
+
+
+#define CAP_LAST_CAP CAP_AUDIT_READ
#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
diff --git a/libcap/include/uapi/linux/securebits.h b/libcap/include/uapi/linux/securebits.h
index 985aac9..35ac35c 100644
--- a/libcap/include/uapi/linux/securebits.h
+++ b/libcap/include/uapi/linux/securebits.h
@@ -43,9 +43,18 @@
#define SECBIT_KEEP_CAPS (issecure_mask(SECURE_KEEP_CAPS))
#define SECBIT_KEEP_CAPS_LOCKED (issecure_mask(SECURE_KEEP_CAPS_LOCKED))
+/* When set, a process cannot add new capabilities to its ambient set. */
+#define SECURE_NO_CAP_AMBIENT_RAISE 6
+#define SECURE_NO_CAP_AMBIENT_RAISE_LOCKED 7 /* make bit-6 immutable */
+
+#define SECBIT_NO_CAP_AMBIENT_RAISE (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))
+#define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED \
+ (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED))
+
#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \
issecure_mask(SECURE_NO_SETUID_FIXUP) | \
- issecure_mask(SECURE_KEEP_CAPS))
+ issecure_mask(SECURE_KEEP_CAPS) | \
+ issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))
#define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1)
#endif /* _UAPI_LINUX_SECUREBITS_H */
diff --git a/progs/Makefile b/progs/Makefile
index 778149e..c094a24 100644
--- a/progs/Makefile
+++ b/progs/Makefile
@@ -4,10 +4,7 @@ include $(topdir)/Make.Rules
#
# Programs: all of the examples that we will compile
#
-PROGS=getpcaps capsh
-ifeq ($(LIBATTR),yes)
-PROGS += getcap setcap
-endif
+PROGS=getpcaps capsh getcap setcap
BUILD=$(PROGS)
diff --git a/progs/quicktest.sh b/progs/quicktest.sh
index ca6bf1e..e8b2c8e 100755
--- a/progs/quicktest.sh
+++ b/progs/quicktest.sh
@@ -89,21 +89,25 @@ if [ $? -ne 0 ]; then
exit 0
fi
+# nobody's uid. Static compilation of the capsh binary can disable pwd
+# info discovery.
+nouid=$(/usr/bin/id nobody -u)
+
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 "./tcapsh --user=nobody"
+fail_capsh --secbits=47 -- -c "./tcapsh --uid=$nouid"
rm -f tcapsh
# Suppress uid=0 privilege
-fail_capsh --secbits=47 --print -- -c "./capsh --user=nobody"
+fail_capsh --secbits=47 --print -- -c "./capsh --uid=$nouid"
# suppress uid=0 privilege and test this privileged
-pass_capsh --secbits=0x2f --print -- -c "./privileged --user=nobody"
+pass_capsh --secbits=0x2f --print -- -c "./privileged --uid=$nouid"
# observe that the bounding set can be used to suppress this forced capability
-fail_capsh --drop=cap_setuid --secbits=0x2f --print -- -c "./privileged --user=nobody"
+fail_capsh --drop=cap_setuid --secbits=0x2f --print -- -c "./privileged --uid=$nouid"
# change the way the capability is obtained (make it inheritable)
./setcap cap_setuid,cap_setgid=ei ./privileged
@@ -111,15 +115,16 @@ fail_capsh --drop=cap_setuid --secbits=0x2f --print -- -c "./privileged --user=n
# 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"
+ --uid=500 --print -- -c "./privileged --uid=$nouid"
rm -f ./privileged
# test that we do not support capabilities on setuid shell-scripts
cat > hack.sh <<EOF
#!/bin/bash
+/usr/bin/id
mypid=\$\$
-caps=\$(./getpcaps \$mypid 2>&1 | cut -d: -f2)
+caps=\$(./getpcaps \$mypid 2>&1 | /usr/bin/cut -d: -f2)
if [ "\$caps" != " =" ]; then
echo "Shell script got [\$caps] - you should upgrade your kernel"
exit 1
@@ -139,7 +144,7 @@ if [ $status -ne 0 ]; then
fi
# Max lockdown
-pass_capsh --keep=1 --user=nobody --caps=cap_setpcap=ep \
+pass_capsh --keep=1 --uid=$nouid --caps=cap_setpcap=ep \
--drop=all --secbits=0x2f --caps= --print
# Verify we can chroot
diff --git a/progs/setcap.c b/progs/setcap.c
index 83090ae..7304343 100644
--- a/progs/setcap.c
+++ b/progs/setcap.c
@@ -171,6 +171,7 @@ int main(int argc, char **argv)
retval = cap_set_file(*++argv, cap_d);
if (retval != 0) {
int explained = 0;
+ int oerrno = errno;
#ifdef linux
cap_value_t cap;
cap_flag_value_t per_state;
@@ -193,7 +194,7 @@ int main(int argc, char **argv)
fprintf(stderr,
"Failed to set capabilities on file `%s' (%s)\n",
- argv[0], strerror(errno));
+ argv[0], strerror(oerrno));
if (!explained) {
usage();
}