Update our copy of libcap. am: 02403a9504
am: b562e4e37c

Change-Id: Id47b57b6a81377d40b80d88da1b5b56fa5fe5cd1
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 @@
 # common defines for libcap
 LIBTITLE=libcap
 VERSION=2
-MINOR=24
+MINOR=25
 #
 
 # Compilation specifics
@@ -70,7 +70,6 @@
 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 @@
 #
 #    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 @@
 # 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 @@
 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 @@
 
 #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 @@
 
 #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 @@
 #
 # 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 @@
     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 @@
 # 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 @@
 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 @@
 	    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 @@
 		
 		fprintf(stderr,
 			"Failed to set capabilities on file `%s' (%s)\n",
-			argv[0], strerror(errno));
+			argv[0], strerror(oerrno));
 		if (!explained) {
 		    usage();
 		}