+CVE: CVE-2020-9272
+Signed-off-by: Hitendra Prajapati <[email protected]>
+---
+ lib/libcap/Makefile | 53 ++-
+ lib/libcap/_makenames.c | 41 +--
+ lib/libcap/cap_alloc.c | 101 +++---
+ lib/libcap/cap_extint.c | 71 ++--
+ lib/libcap/cap_file.c | 314 +++++++++++++++---
+ lib/libcap/cap_flag.c | 99 +++---
+ lib/libcap/cap_proc.c | 169 +++++++---
+ lib/libcap/cap_sys.c | 41 ---
+ lib/libcap/cap_text.c | 301 +++++++++++------
+ lib/libcap/include/sys/capability.h | 74 +++--
+ lib/libcap/include/sys/securebits.h | 22 ++
+ lib/libcap/include/uapi/linux/capability.h | 367
+++++++++++++++++++++
+ lib/libcap/include/uapi/linux/prctl.h | 200 +++++++++++
+ lib/libcap/include/uapi/linux/securebits.h | 60 ++++
+ lib/libcap/libcap.h | 223 +++++++------
+ 15 files changed, 1538 insertions(+), 598 deletions(-)
+ delete mode 100644 lib/libcap/cap_sys.c
+ create mode 100644 lib/libcap/include/sys/securebits.h
+ create mode 100644 lib/libcap/include/uapi/linux/capability.h
+ create mode 100644 lib/libcap/include/uapi/linux/prctl.h
+ create mode 100644 lib/libcap/include/uapi/linux/securebits.h
+
+diff --git a/lib/libcap/Makefile b/lib/libcap/Makefile
+index d5311ce..ff88cfb 100644
+--- a/lib/libcap/Makefile
++++ b/lib/libcap/Makefile
+@@ -1,5 +1,5 @@
+-## This libcap (for proftpd) is originally from libcap-1.10,
+-## at ftp://linux.kernel.org/pub/libs/security/linux-privs.
++## This libcap (for proftpd) is originally from libcap, at:
++## https://github.com/mhiramat/libcap.git.
+ ## This interface is SPECIFIC TO THE LINUX 2.2 KERNEL!!! IT IS NOT
GUARANTEED
+ ## TO WORK ON ANY PRIOR OR LATER VERSION (ie: 2.1.x or 2.3.x).
+ ## If this library stops working, please contact [email protected].
+@@ -9,50 +9,49 @@
+ #
+ topdir=$(shell pwd)/..
+ include ../../Make.rules
++
++KERNEL_HEADERS=/usr/include
++LIBTITLE=libcap
++
+ #
+ # Library version
+ #
+-LIBNAME=libcap.a
++LIBNAME=$(LIBTITLE).so
++STALIBNAME=$(LIBTITLE).a
+ #
+
+-FILES=cap_alloc cap_proc cap_extint cap_flag cap_text cap_sys
+-
+-# for later when there is filesystem support for cap's:
+-#FILES += cap_file
++FILES=cap_alloc cap_proc cap_extint cap_flag cap_text cap_file
+
+ INCLS=libcap.h cap_names.h $(INCS)
+ OBJS=$(addsuffix .o, $(FILES))
+
+-all: $(LIBNAME)
++all: $(STALIBNAME)
+
+-_makenames: _makenames.c cap_names.sed
+- $(BUILD_CC) $(CFLAGS) $(LDFLAGS) $< -o $@
++_makenames: _makenames.c cap_names.list.h
++ $(CC) $(CFLAGS) $< -o $@
+
+ cap_names.h: _makenames
+ ./_makenames > cap_names.h
+
+-cap_names.sed: Makefile /usr/include/linux/capability.h
+- @echo "=> making cap_names.c from <linux/capability.h>"
+- @sed -ne '/^#define[ \t]CAP[_A-Z]\+[ \t]\+[0-
9]\+/{s/^#define \([^ \t]*\)[ \t]*\([^ \t]*\)/ \{ \2, \"\1\"
\},/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' <
/usr/include/linux/capability.h | fgrep -v 0x > cap_names.sed
+-# @sed -ne '/^#define[ \t]CAP[_A-Z]\+[ \t]\+[0-
9]\+/{s/^#define CAP_\([^ \t]*\)[ \t]*\([^ \t]*\)/ \{ \2, \"\1\"
\},/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' <
/usr/include/linux/capability.h | fgrep -v 0x > cap_names.sed
++cap_names.list.h: Makefile $(KERNEL_HEADERS)/linux/capability.h
++ @echo "=> making $@ from
$(KERNEL_HEADERS)/linux/capability.h"
++ perl -e 'while ($$l=<>) { if ($$l =~ /^\#define[ \t](CAP[_A-
Z]+)[ \t]+([0-9]+)\s+$$/) { $$tok=$$1; $$val=$$2; $$tok =~ tr/A-Z/a-
z/; print "{\"$$tok\",$$val},\n"; } }'
$(KERNEL_HEADERS)/linux/capability.h | fgrep -v 0x > $@
+
+-$(LIBNAME): $(OBJS)
+- ar rcu $@ $(OBJS)
++$(STALIBNAME): $(OBJS)
++ $(AR) rcs $@ $^
++ $(RANLIB) $@
+
+ %.o: %.c $(INCLS)
+- $(CC) $(CFLAGS) -c $< -o $@
++ $(CC) $(CFLAGS) $(IPATH) -c $< -o $@
++
++cap_text.o: cap_text.c $(INCLS)
++ $(CC) $(CFLAGS) $(IPATH) -c $< -o $@
+
+ install: all
+- mkdir -p -m 0755 $(INCDIR)/sys
+- install -m 0644 include/sys/capability.h $(INCDIR)/sys
+- mkdir -p -m 0755 $(LIBDIR)
+- install -m 0644 $(MINLIBNAME) $(LIBDIR)/$(MINLIBNAME)
+- ln -sf $(MINLIBNAME) $(LIBDIR)/$(MAJLIBNAME)
+- ln -sf $(MAJLIBNAME) $(LIBDIR)/$(LIBNAME)
++ mkdir -p -m 0755 $(FAKEROOT)$(INCDIR)/sys
++ install -m 0644 include/sys/capability.h
$(FAKEROOT)$(INCDIR)/sys
+ -/sbin/ldconfig
+
+ clean:
+- $(LOCALCLEAN)
+- rm -f $(OBJS) $(LIBNAME)*
+- rm -f cap_names.h cap_names.sed _makenames
+-
++ rm -f $(OBJS) $(LIBNAME)* $(STALIBNAME)
++ rm -f cap_names.h cap_names.list.h _makenames
+diff --git a/lib/libcap/_makenames.c b/lib/libcap/_makenames.c
+index ddbaf05..e37bedb 100644
+--- a/lib/libcap/_makenames.c
++++ b/lib/libcap/_makenames.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997-8 Andrew G. Morgan <[email protected]>
++ * Copyright (c) 1997-8 Andrew G. Morgan <[email protected]>
+ *
+ * This is a file to make the capability <-> string mappings for
+ * libcap.
+@@ -14,11 +14,11 @@
+ */
+
+ struct {
+- int index;
+ const char *name;
++ int index;
+ } const list[] = {
+-#include "cap_names.sed"
+- {-1, NULL}
++#include "cap_names.list.h"
++ {NULL, -1}
+ };
+
+ /* this should be more than big enough (factor of three at least)
*/
+@@ -59,36 +59,3 @@ int main(void)
+
+ exit(0);
+ }
+-
+-/*
+- * $Log: _makenames.c,v $
+- * Revision 1.1 2003-01-03 02:16:17 jwm
+- *
+- * Turning mod_linuxprivs into a core module, mod_cap. This is by
no means
+- * complete.
+- *
+- * Revision 1.2 1999/09/07 23:14:19 macgyver
+- * Updated capabilities library and model.
+- *
+- * Revision 1.3 1999/05/14 04:46:15 morgan
+- * another attempt to fix the bug Chris Evans found
+- *
+- * Revision 1.2 1999/05/14 04:38:06 morgan
+- * Fix from Chris Evans: off by one error when computing the name
array
+- *
+- * Revision 1.1.1.1 1999/04/17 22:16:31 morgan
+- * release 1.0 of libcap
+- *
+- * Revision 1.4 1998/06/07 15:50:12 morgan
+- * updated to accommodate kernel's real header file :*)
+- *
+- * Revision 1.3 1998/05/24 22:54:09 morgan
+- * updated for 2.1.104
+- *
+- * Revision 1.2 1997/05/04 05:35:46 morgan
+- * cleaned up to #include sed output. also generates whole
cap_names.c file
+- *
+- * Revision 1.1 1997/04/28 00:57:11 morgan
+- * Initial revision
+- *
+- */
+diff --git a/lib/libcap/cap_alloc.c b/lib/libcap/cap_alloc.c
+index c5962f0..525ea90 100644
+--- a/lib/libcap/cap_alloc.c
++++ b/lib/libcap/cap_alloc.c
+@@ -1,7 +1,5 @@
+ /*
+- * Copyright (c) 1997-8 Andrew G Morgan <[email protected]>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997-8 Andrew G Morgan <[email protected]>
+ *
+ * This file deals with allocation and deallocation of internal
+ * capability sets as specified by POSIX.1e (formerlly, POSIX 6).
+@@ -10,7 +8,6 @@
+ #include "libcap.h"
+
+ /*
+- * This function duplicates an internal capability set (x3) with
+ * Obtain a blank set of capabilities
+ */
+
+@@ -22,16 +19,36 @@ cap_t cap_init(void)
+ raw_data = malloc( sizeof(__u32) + sizeof(*result) );
+
+ if (raw_data == NULL) {
+- _cap_debug("out of memory");
+- errno = ENOMEM;
+- return NULL;
++ _cap_debug("out of memory");
++ errno = ENOMEM;
++ return NULL;
+ }
+
+ *raw_data = CAP_T_MAGIC;
+ result = (cap_t) (raw_data + 1);
+ memset(result, 0, sizeof(*result));
+
+- result->head.version = _LINUX_CAPABILITY_VERSION_1;
++ result->head.version = _LIBCAP_CAPABILITY_VERSION;
++ capget(&result->head, NULL); /* load the kernel-capability
version */
++
++ switch (result->head.version) {
++#ifdef _LINUX_CAPABILITY_VERSION_1
++ case _LINUX_CAPABILITY_VERSION_1:
++ break;
++#endif
++#ifdef _LINUX_CAPABILITY_VERSION_2
++ case _LINUX_CAPABILITY_VERSION_2:
++ break;
++#endif
++#ifdef _LINUX_CAPABILITY_VERSION_3
++ case _LINUX_CAPABILITY_VERSION_3:
++ break;
++#endif
++ default: /* No idea what to do */
++ cap_free(result);
++ result = NULL;
++ break;
++ }
+
+ return result;
+ }
+@@ -46,14 +63,14 @@ char *_libcap_strdup(const char *old)
+ __u32 *raw_data;
+
+ if (old == NULL) {
+- errno = EINVAL;
+- return NULL;
++ errno = EINVAL;
++ return NULL;
+ }
+
+ raw_data = malloc( sizeof(__u32) + strlen(old) + 1 );
+ if (raw_data == NULL) {
+- errno = ENOMEM;
+- return NULL;
++ errno = ENOMEM;
++ return NULL;
+ }
+
+ *(raw_data++) = CAP_S_MAGIC;
+@@ -96,61 +113,27 @@ cap_t cap_dup(cap_t cap_d)
+
+ int cap_free(void *data_p)
+ {
++ if ( !data_p )
++ return 0;
+
+ if ( good_cap_t(data_p) ) {
+- data_p = -1 + (__u32 *) data_p;
+- memset(data_p, 0, sizeof(__u32) + sizeof(struct
_cap_struct));
+- free(data_p);
+- data_p = NULL;
+- return 0;
++ data_p = -1 + (__u32 *) data_p;
++ memset(data_p, 0, sizeof(__u32) + sizeof(struct
_cap_struct));
++ free(data_p);
++ data_p = NULL;
++ return 0;
+ }
+
+ if ( good_cap_string(data_p) ) {
+- int length = strlen(data_p) + sizeof(__u32);
+- data_p = -1 + (__u32 *) data_p;
+- memset(data_p, 0, length);
+- free(data_p);
+- data_p = NULL;
+- return 0;
++ size_t length = strlen(data_p) + sizeof(__u32);
++ data_p = -1 + (__u32 *) data_p;
++ memset(data_p, 0, length);
++ free(data_p);
++ data_p = NULL;
++ return 0;
+ }
+
+ _cap_debug("don't recognize what we're supposed to liberate");
+ errno = EINVAL;
+ return -1;
+ }
+-
+-/*
+- * $Log: cap_alloc.c,v $
+- * Revision 1.3 2008-08-06 17:00:41 castaglia
+- *
+- * Bug#3096 - libcap version errors on newer Linux kernel. Newer
Linux kernels
+- * have a _LINUX_CAPABILITY_VERSION_2 macro, and redefine the old
+- * _LINUX_CAPABILITY_VERSION macro. To play better with such
kernels, redefine
+- * the bundled libcap to use _LINUX_CAPABILITY_VERSION_1.
+- *
+- * Revision 1.2 2003/05/15 00:49:13 castaglia
+- *
+- * Bug#2000 - mod_cap should not use bundled libcap. This patch
updates the
+- * bundled libcap; I won't be closing the bug report just yet.
+- *
+- * Revision 1.1 2003/01/03 02:16:17 jwm
+- *
+- * Turning mod_linuxprivs into a core module, mod_cap. This is by
no means
+- * complete.
+- *
+- * Revision 1.2 1999/09/07 23:14:19 macgyver
+- * Updated capabilities library and model.
+- *
+- * Revision 1.1.1.1 1999/04/17 22:16:31 morgan
+- * release 1.0 of libcap
+- *
+- * Revision 1.3 1998/05/24 22:54:09 morgan
+- * updated for 2.1.104
+- *
+- * Revision 1.2 1997/04/28 00:57:11 morgan
+- * fixes and zefram's patches
+- *
+- * Revision 1.1 1997/04/21 04:32:52 morgan
+- * Initial revision
+- *
+- */
+diff --git a/lib/libcap/cap_extint.c b/lib/libcap/cap_extint.c
+index 75ce508..7d6e7ad 100644
+--- a/lib/libcap/cap_extint.c
++++ b/lib/libcap/cap_extint.c
+@@ -1,7 +1,5 @@
+ /*
+- * Copyright (c) 1997-8 Andrew G Morgan <[email protected]>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997-8 Andrew G Morgan <[email protected]>
+ *
+ * This file deals with exchanging internal and external
+ * representations of capability sets.
+@@ -11,7 +9,7 @@
+
+ /*
+ * External representation for capabilities. (exported as a fixed
+- * length (void *))
++ * length)
+ */
+ #define CAP_EXT_MAGIC "\220\302\001\121"
+ #define CAP_EXT_MAGIC_SIZE 4
+@@ -20,8 +18,10 @@ const static __u8
external_magic[CAP_EXT_MAGIC_SIZE+1] = CAP_EXT_MAGIC;
+ struct cap_ext_struct {
+ __u8 magic[CAP_EXT_MAGIC_SIZE];
+ __u8 length_of_capset;
+-/* note, we arrange these so the caps are stacked with byte-size
+- resolution */
++ /*
++ * note, we arrange these so the caps are stacked with byte-
size
++ * resolution
++ */
+ __u8 bytes[CAP_SET_SIZE][NUMBER_OF_CAP_SETS];
+ };
+
+@@ -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);
+ }
+
+ /*
+@@ -43,11 +43,10 @@ ssize_t cap_size(cap_t caps)
+ ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length)
+ {
+ struct cap_ext_struct *result = (struct cap_ext_struct *)
cap_ext;
+- __u32 *from = (__u32 *) &(cap_d->set);
+ 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;
+@@ -58,9 +57,11 @@ 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 = *from++;
++ __u32 val;
++
++ val = cap_d->u[j/sizeof(__u32)].flat[i];
+
+ result->bytes[j++][i] = val & 0xFF;
+ result->bytes[j++][i] = (val >>= 8) & 0xFF;
+@@ -70,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));
+ }
+
+ /*
+@@ -78,22 +79,16 @@ ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d,
ssize_t length)
+ * the internal rep should be liberated with cap_free().
+ */
+
+-/*
+- * XXX - need to take a little more care when importing small
+- * capability sets.
+- */
+-
+ cap_t cap_copy_int(const void *cap_ext)
+ {
+ const struct cap_ext_struct *export =
+ (const struct cap_ext_struct *) cap_ext;
+- cap_t cap_d = NULL;
++ cap_t cap_d;
+ int set, blen;
+- __u32 * to = (__u32 *) &cap_d->set;
+
+ /* Does the external representation make sense? */
+- if (export == NULL || !memcmp(export->magic, external_magic
+- , CAP_EXT_MAGIC_SIZE)) {
++ if ((export == NULL)
++ || memcmp(export->magic, external_magic,
CAP_EXT_MAGIC_SIZE)) {
+ errno = EINVAL;
+ return NULL;
+ }
+@@ -103,10 +98,10 @@ cap_t cap_copy_int(const void *cap_ext)
+ return NULL;
+
+ blen = export->length_of_capset;
+- for (set=0; set<=NUMBER_OF_CAP_SETS; ++set) {
+- int blk;
++ for (set=0; set<NUMBER_OF_CAP_SETS; ++set) {
++ unsigned blk;
+ int bno = 0;
+- for (blk=0; blk<(CAP_SET_SIZE/4); ++blk) {
++ for (blk=0; blk<(CAP_SET_SIZE/sizeof(__u32)); ++blk) {
+ __u32 val = 0;
+
+ if (bno != blen)
+@@ -118,7 +113,7 @@ cap_t cap_copy_int(const void *cap_ext)
+ if (bno != blen)
+ val |= export->bytes[bno++][set] << 24;
+
+- *to++ = val;
++ cap_d->u[blk].flat[set] = val;
+ }
+ }
+
+@@ -126,29 +121,3 @@ cap_t cap_copy_int(const void *cap_ext)
+ return cap_d;
+ }
+
+-/*
+- * $Log: cap_extint.c,v $
+- * Revision 1.1 2003-01-03 02:16:17 jwm
+- *
+- * Turning mod_linuxprivs into a core module, mod_cap. This is by
no means
+- * complete.
+- *
+- * Revision 1.3 1999/09/17 03:54:08 macgyver
+- * Corrected gcc warning.
+- *
+- * Revision 1.2 1999/09/07 23:14:19 macgyver
+- * Updated capabilities library and model.
+- *
+- * Revision 1.1.1.1 1999/04/17 22:16:31 morgan
+- * release 1.0 of libcap
+- *
+- * Revision 1.3 1998/05/24 22:54:09 morgan
+- * updated for 2.1.104
+- *
+- * Revision 1.2 1997/04/28 00:57:11 morgan
+- * fixes and zefram's patches
+- *
+- * Revision 1.1 1997/04/21 04:32:52 morgan
+- * Initial revision
+- *
+- */
+diff --git a/lib/libcap/cap_file.c b/lib/libcap/cap_file.c
+index 65522f4..76aac8c 100644
+--- a/lib/libcap/cap_file.c
++++ b/lib/libcap/cap_file.c
+@@ -1,13 +1,183 @@
+ /*
+- * Copyright (c) 1997 Andrew G Morgan <[email protected]>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997,2007,2016 Andrew G Morgan <[email protected]>
+ *
+ * This file deals with setting capabilities on files.
+ */
+
++#include <sys/types.h>
++#include <byteswap.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <linux/xattr.h>
++
++/*
++ * 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"
+
++#ifdef VFS_CAP_U32
++
++#if VFS_CAP_U32 != __CAP_BLKS
++# error VFS representation of capabilities is not the same size as
kernel
++#endif
++
++#if __BYTE_ORDER == __BIG_ENDIAN
++#define FIXUP_32BITS(x) bswap_32(x)
++#else
++#define FIXUP_32BITS(x) (x)
++#endif
++
++static cap_t _fcaps_load(struct vfs_cap_data *rawvfscap, cap_t
result,
++ int bytes)
++{
++ __u32 magic_etc;
++ unsigned tocopy, i;
++
++ magic_etc = FIXUP_32BITS(rawvfscap->magic_etc);
++ switch (magic_etc & VFS_CAP_REVISION_MASK) {
++#ifdef VFS_CAP_REVISION_1
++ case VFS_CAP_REVISION_1:
++ tocopy = VFS_CAP_U32_1;
++ bytes -= XATTR_CAPS_SZ_1;
++ break;
++#endif
++
++#ifdef VFS_CAP_REVISION_2
++ case VFS_CAP_REVISION_2:
++ tocopy = VFS_CAP_U32_2;
++ bytes -= XATTR_CAPS_SZ_2;
++ break;
++#endif
++
++ default:
++ cap_free(result);
++ result = NULL;
++ return result;
++ }
++
++ /*
++ * Verify that we loaded exactly the right number of bytes
++ */
++ if (bytes != 0) {
++ cap_free(result);
++ result = NULL;
++ return result;
++ }
++
++ for (i=0; i < tocopy; i++) {
++ result->u[i].flat[CAP_INHERITABLE]
++ = FIXUP_32BITS(rawvfscap->data[i].inheritable);
++ result->u[i].flat[CAP_PERMITTED]
++ = FIXUP_32BITS(rawvfscap->data[i].permitted);
++ if (magic_etc & VFS_CAP_FLAGS_EFFECTIVE) {
++ result->u[i].flat[CAP_EFFECTIVE]
++ = result->u[i].flat[CAP_INHERITABLE]
++ | result->u[i].flat[CAP_PERMITTED];
++ }
++ }
++ while (i < __CAP_BLKS) {
++ result->u[i].flat[CAP_INHERITABLE]
++ = result->u[i].flat[CAP_PERMITTED]
++ = result->u[i].flat[CAP_EFFECTIVE] = 0;
++ i++;
++ }
++
++ return result;
++}
++
++static int _fcaps_save(struct vfs_cap_data *rawvfscap, cap_t cap_d,
++ int *bytes_p)
++{
++ __u32 eff_not_zero, magic;
++ unsigned tocopy, i;
++
++ if (!good_cap_t(cap_d)) {
++ errno = EINVAL;
++ return -1;
++ }
++
++ switch (cap_d->head.version) {
++#ifdef _LINUX_CAPABILITY_VERSION_1
++ case _LINUX_CAPABILITY_VERSION_1:
++ magic = VFS_CAP_REVISION_1;
++ tocopy = VFS_CAP_U32_1;
++ *bytes_p = XATTR_CAPS_SZ_1;
++ break;
++#endif
++
++#ifdef _LINUX_CAPABILITY_VERSION_2
++ case _LINUX_CAPABILITY_VERSION_2:
++ magic = VFS_CAP_REVISION_2;
++ tocopy = VFS_CAP_U32_2;
++ *bytes_p = XATTR_CAPS_SZ_2;
++ break;
++#endif
++
++#ifdef _LINUX_CAPABILITY_VERSION_3
++ case _LINUX_CAPABILITY_VERSION_3:
++ magic = VFS_CAP_REVISION_2;
++ tocopy = VFS_CAP_U32_2;
++ *bytes_p = XATTR_CAPS_SZ_2;
++ break;
++#endif
++
++ default:
++ errno = EINVAL;
++ return -1;
++ }
++
++ _cap_debug("setting named file capabilities");
++
++ for (eff_not_zero = 0, i = 0; i < tocopy; i++) {
++ eff_not_zero |= cap_d->u[i].flat[CAP_EFFECTIVE];
++ }
++ while (i < __CAP_BLKS) {
++ if ((cap_d->u[i].flat[CAP_EFFECTIVE]
++ || cap_d->u[i].flat[CAP_INHERITABLE]
++ || cap_d->u[i].flat[CAP_PERMITTED])) {
++ /*
++ * System does not support these capabilities
++ */
++ errno = EINVAL;
++ return -1;
++ }
++ i++;
++ }
++
++ for (i=0; i < tocopy; i++) {
++ rawvfscap->data[i].permitted
++ = FIXUP_32BITS(cap_d->u[i].flat[CAP_PERMITTED]);
++ rawvfscap->data[i].inheritable
++ = FIXUP_32BITS(cap_d->u[i].flat[CAP_INHERITABLE]);
++
++ if (eff_not_zero
++ && ((~(cap_d->u[i].flat[CAP_EFFECTIVE]))
++ & (cap_d->u[i].flat[CAP_PERMITTED]
++ | cap_d->u[i].flat[CAP_INHERITABLE]))) {
++ errno = EINVAL;
++ return -1;
++ }
++ }
++
++ if (eff_not_zero == 0) {
++ rawvfscap->magic_etc = FIXUP_32BITS(magic);
++ } else {
++ rawvfscap->magic_etc =
FIXUP_32BITS(magic|VFS_CAP_FLAGS_EFFECTIVE);
++ }
++
++ return 0; /* success */
++}
++
+ /*
+ * Get the capabilities of an open file, as specified by its file
+ * descriptor.
+@@ -20,14 +190,19 @@ cap_t cap_get_fd(int fildes)
+ /* allocate a new capability set */
+ result = cap_init();
+ if (result) {
++ struct vfs_cap_data rawvfscap;
++ int sizeofcaps;
++
+ _cap_debug("getting fildes capabilities");
+
+ /* fill the capability sets via a system call */
+- if (_fgetfilecap(fildes, sizeof(struct __cap_s),
+- &result->set[CAP_INHERITABLE],
+- &result->set[CAP_PERMITTED],
+- &result->set[CAP_EFFECTIVE] )) {
+- cap_free(&result);
++ sizeofcaps = fgetxattr(fildes, XATTR_NAME_CAPS,
++ &rawvfscap, sizeof(rawvfscap));
++ if (sizeofcaps < ssizeof(rawvfscap.magic_etc)) {
++ cap_free(result);
++ result = NULL;
++ } else {
++ result = _fcaps_load(&rawvfscap, result, sizeofcaps);
+ }
+ }
+
+@@ -35,7 +210,7 @@ cap_t cap_get_fd(int fildes)
+ }
+
+ /*
+- * Set the capabilities on a named file.
++ * Get the capabilities from a named file.
+ */
+
+ cap_t cap_get_file(const char *filename)
+@@ -45,14 +220,20 @@ cap_t cap_get_file(const char *filename)
+ /* allocate a new capability set */
+ result = cap_init();
+ if (result) {
+- _cap_debug("getting named file capabilities");
++ struct vfs_cap_data rawvfscap;
++ int sizeofcaps;
++
++ _cap_debug("getting filename capabilities");
+
+ /* fill the capability sets via a system call */
+- if (_getfilecap(filename, sizeof(struct __cap_s),
+- &result->set[CAP_INHERITABLE],
+- &result->set[CAP_PERMITTED],
+- &result->set[CAP_EFFECTIVE] ))
+- cap_free(&result);
++ sizeofcaps = getxattr(filename, XATTR_NAME_CAPS,
++ &rawvfscap, sizeof(rawvfscap));
++ if (sizeofcaps < ssizeof(rawvfscap.magic_etc)) {
++ cap_free(result);
++ result = NULL;
++ } else {
++ result = _fcaps_load(&rawvfscap, result, sizeofcaps);
++ }
+ }
+
+ return result;
+@@ -65,16 +246,30 @@ cap_t cap_get_file(const char *filename)
+
+ int cap_set_fd(int fildes, cap_t cap_d)
+ {
+- if (!good_cap_t(cap_d)) {
++ struct vfs_cap_data rawvfscap;
++ int sizeofcaps;
++ struct stat buf;
++
++ if (fstat(fildes, &buf) != 0) {
++ _cap_debug("unable to stat file descriptor %d", fildes);
++ return -1;
++ }
++ if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) {
++ _cap_debug("file descriptor %d for non-regular file",
fildes);
+ errno = EINVAL;
+ return -1;
+ }
+
++ if (cap_d == NULL) {
++ _cap_debug("deleting fildes capabilities");
++ return fremovexattr(fildes, XATTR_NAME_CAPS);
++ } else if (_fcaps_save(&rawvfscap, cap_d, &sizeofcaps) != 0) {
++ return -1;
++ }
++
+ _cap_debug("setting fildes capabilities");
+- return _fsetfilecap(fildes, sizeof(struct __cap_s),
+- &cap_d->set[CAP_INHERITABLE],
+- &cap_d->set[CAP_PERMITTED],
+- &cap_d->set[CAP_EFFECTIVE] );
++
++ return fsetxattr(fildes, XATTR_NAME_CAPS, &rawvfscap,
sizeofcaps, 0);
+ }
+
+ /*
+@@ -83,44 +278,55 @@ int cap_set_fd(int fildes, cap_t cap_d)
+
+ int cap_set_file(const char *filename, cap_t cap_d)
+ {
+- if (!good_cap_t(cap_d)) {
++ struct vfs_cap_data rawvfscap;
++ int sizeofcaps;
++ struct stat buf;
++
++ if (lstat(filename, &buf) != 0) {
++ _cap_debug("unable to stat file [%s]", filename);
++ return -1;
++ }
++ if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) {
++ _cap_debug("file [%s] is not a regular file", filename);
+ errno = EINVAL;
+ return -1;
+ }
+
++ if (cap_d == NULL) {
++ _cap_debug("removing filename capabilities");
++ return removexattr(filename, XATTR_NAME_CAPS);
++ } else if (_fcaps_save(&rawvfscap, cap_d, &sizeofcaps) != 0) {
++ return -1;
++ }
++
+ _cap_debug("setting filename capabilities");
+- return _setfilecap(filename, sizeof(struct __cap_s),
+- &cap_d->set[CAP_INHERITABLE],
+- &cap_d->set[CAP_PERMITTED],
+- &cap_d->set[CAP_EFFECTIVE] );
++ return setxattr(filename, XATTR_NAME_CAPS, &rawvfscap,
sizeofcaps, 0);
+ }
+
+-/*
+- * $Log: cap_file.c,v $
+- * Revision 1.1 2003-01-03 02:16:17 jwm
+- *
+- * Turning mod_linuxprivs into a core module, mod_cap. This is by
no means
+- * complete.
+- *
+- * Revision 1.1 1999/09/07 23:14:19 macgyver
+- * Updated capabilities library and model.
+- *
+- * Revision 1.1.1.1 1999/04/17 22:16:31 morgan
+- * release 1.0 of libcap
+- *
+- * Revision 1.5 1998/05/24 22:54:09 morgan
+- * updated for 2.1.104
+- *
+- * Revision 1.4 1997/05/14 05:17:13 morgan
+- * bug-fix from zefram (errno no set on success)
+- *
+- * Revision 1.3 1997/05/04 05:35:46 morgan
+- * fixed errno setting. syscalls do this part
+- *
+- * Revision 1.2 1997/04/28 00:57:11 morgan
+- * fixes and zefram's patches
+- *
+- * Revision 1.1 1997/04/21 04:32:52 morgan
+- * Initial revision
+- *
+- */
++#else /* ie. ndef VFS_CAP_U32 */
++
++cap_t cap_get_fd(int fildes)
++{
++ errno = EINVAL;
++ return NULL;
++}
++
++cap_t cap_get_file(const char *filename)
++{
++ errno = EINVAL;
++ return NULL;
++}
++
++int cap_set_fd(int fildes, cap_t cap_d)
++{
++ errno = EINVAL;
++ return -1;
++}
++
++int cap_set_file(const char *filename, cap_t cap_d)
++{
++ errno = EINVAL;
++ return -1;
++}
++
++#endif /* def VFS_CAP_U32 */
+diff --git a/lib/libcap/cap_flag.c b/lib/libcap/cap_flag.c
+index f78dc05..52ec3b3 100644
+--- a/lib/libcap/cap_flag.c
++++ b/lib/libcap/cap_flag.c
+@@ -1,7 +1,5 @@
+ /*
+- * Copyright (c) 1997-8 Andrew G. Morgan <[email protected]>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997-8,2008 Andrew G. Morgan <[email protected]>
+ *
+ * This file deals with flipping of capabilities on internal
+ * capability sets as specified by POSIX.1e (formerlly, POSIX 6).
+@@ -25,18 +23,12 @@ int cap_get_flag(cap_t cap_d, cap_value_t value,
cap_flag_t set,
+
+ if (raised && good_cap_t(cap_d) && value >= 0 && value <
__CAP_BITS
+ && set >= 0 && set < NUMBER_OF_CAP_SETS) {
+- __cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE
+- + (__u8 *) &cap_d->set);
+-
+- *raised = isset_cap(cap_p,value) ? CAP_SET:CAP_CLEAR;
++ *raised = isset_cap(cap_d,value,set) ? CAP_SET:CAP_CLEAR;
+ return 0;
+-
+ } else {
+-
+ _cap_debug("invalid arguments");
+ errno = EINVAL;
+ return -1;
+-
+ }
+ }
+
+@@ -45,7 +37,7 @@ int cap_get_flag(cap_t cap_d, cap_value_t value,
cap_flag_t set,
+ */
+
+ int cap_set_flag(cap_t cap_d, cap_flag_t set,
+- int no_values, cap_value_t *array_values,
++ int no_values, const cap_value_t *array_values,
+ cap_flag_value_t raise)
+ {
+ /*
+@@ -62,13 +54,11 @@ int cap_set_flag(cap_t cap_d, cap_flag_t set,
+ _cap_debug("weird capability (%d) - skipped",
array_values[i]);
+ } else {
+ int value = array_values[i];
+- __cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE
+- + (__u8 *) &cap_d-
set);
+
+ if (raise == CAP_SET) {
+- cap_p->raise_cap(value);
++ cap_d->raise_cap(value,set);
+ } else {
+- cap_p->lower_cap(value);
++ cap_d->lower_cap(value,set);
+ }
+ }
+ }
+@@ -91,7 +81,7 @@ int cap_clear(cap_t cap_d)
+ {
+ if (good_cap_t(cap_d)) {
+
+- memset(&(cap_d->set), 0, sizeof(cap_d->set));
++ memset(&(cap_d->u), 0, sizeof(cap_d->u));
+ return 0;
+
+ } else {
+@@ -104,28 +94,57 @@ int cap_clear(cap_t cap_d)
+ }
+
+ /*
+- * $Log: cap_flag.c,v $
+- * Revision 1.1 2003-01-03 02:16:17 jwm
+- *
+- * Turning mod_linuxprivs into a core module, mod_cap. This is by
no means
+- * complete.
+- *
+- * Revision 1.2 1999/09/07 23:14:19 macgyver
+- * Updated capabilities library and model.
+- *
+- * Revision 1.1.1.1 1999/04/17 22:16:31 morgan
+- * release 1.0 of libcap
+- *
+- * Revision 1.4 1998/09/20 23:07:59 morgan
+- * fixed lower bound check on 'set'.
+- *
+- * Revision 1.3 1998/05/24 22:54:09 morgan
+- * updated for 2.1.104
+- *
+- * Revision 1.2 1997/04/28 00:57:11 morgan
+- * fixes and zefram's patches
+- *
+- * Revision 1.1 1997/04/21 04:32:52 morgan
+- * Initial revision
+- *
++ * Reset the all of the capability bits for one of the flag sets
++ */
++
++int cap_clear_flag(cap_t cap_d, cap_flag_t flag)
++{
++ switch (flag) {
++ case CAP_EFFECTIVE:
++ case CAP_PERMITTED:
++ case CAP_INHERITABLE:
++ if (good_cap_t(cap_d)) {
++ unsigned i;
++
++ for (i=0; i<_LIBCAP_CAPABILITY_U32S; i++) {
++ cap_d->u[i].flat[flag] = 0;
++ }
++ return 0;
++ }
++ /*
++ * fall through
++ */
++
++ default:
++ _cap_debug("invalid pointer");
++ errno = EINVAL;
++ return -1;
++ }
++}
++
++/*
++ * Compare two capability sets
+ */
++
++int cap_compare(cap_t a, cap_t b)
++{
++ unsigned i;
++ int result;
++
++ if (!(good_cap_t(a) && good_cap_t(b))) {
++ _cap_debug("invalid arguments");
++ errno = EINVAL;
++ return -1;
++ }
++
++ �� for (i=0, result=0; i<_LIBCAP_CAPABILITY_U32S; i++) {
++ result |=
++ ((a->u[i].flat[CAP_EFFECTIVE] != b-
u[i].flat[CAP_EFFECTIVE])
++ ? LIBCAP_EFF : 0)
++ | ((a->u[i].flat[CAP_INHERITABLE] != b-
u[i].flat[CAP_INHERITABLE])
++ ? LIBCAP_INH : 0)
++ | ((a->u[i].flat[CAP_PERMITTED] != b-
u[i].flat[CAP_PERMITTED])
++ ? LIBCAP_PER : 0);
++ }
++ return result;
++}
+diff --git a/lib/libcap/cap_proc.c b/lib/libcap/cap_proc.c
+index 73a02d5..f70b0e3 100644
+--- a/lib/libcap/cap_proc.c
++++ b/lib/libcap/cap_proc.c
+@@ -1,11 +1,11 @@
+ /*
+- * Copyright (c) 1997-8 Andrew G Morgan <[email protected]>
++ * Copyright (c) 1997-8,2007,2011 Andrew G Morgan
<[email protected]>
+ *
+- * See end of file for Log.
+- *
+- * This file deals with setting capabilities on processes.
++ * This file deals with getting and setting capabilities on
processes.
+ */
+
++#include <sys/prctl.h>
++
+ #include "libcap.h"
+
+ cap_t cap_get_proc(void)
+@@ -18,8 +18,9 @@ cap_t cap_get_proc(void)
+ _cap_debug("getting current process' capabilities");
+
+ /* fill the capability sets via a system call */
+- if (capget(&result->head, &result->set)) {
+- cap_free(&result);
++ if (capget(&result->head, &result->u[0].set)) {
++ cap_free(result);
++ result = NULL;
+ }
+ }
+
+@@ -36,9 +37,8 @@ int cap_set_proc(cap_t cap_d)
+ }
+
+ _cap_debug("setting process capabilities");
+- retval = capset(&cap_d->head, &cap_d->set);
++ retval = capset(&cap_d->head, &cap_d->u[0].set);
+
+- cap_d->head.version = _LINUX_CAPABILITY_VERSION_1;
+ return retval;
+ }
+
+@@ -58,13 +58,33 @@ int capgetp(pid_t pid, cap_t cap_d)
+ _cap_debug("getting process capabilities for proc %d", pid);
+
+ cap_d->head.pid = pid;
+- error = capget(&cap_d->head, &cap_d->set);
+- cap_d->head.version = _LINUX_CAPABILITY_VERSION_1;
++ error = capget(&cap_d->head, &cap_d->u[0].set);
+ cap_d->head.pid = 0;
+
+ return error;
+ }
+
++/* allocate space for and return capabilities of target process */
++
++cap_t cap_get_pid(pid_t pid)
++{
++ cap_t result;
++
++ result = cap_init();
++ if (result) {
++ if (capgetp(pid, result) != 0) {
++ int my_errno;
++
++ my_errno = errno;
++ cap_free(result);
++ errno = my_errno;
++ result = NULL;
++ }
++ }
++
++ return result;
++}
++
+ /* set the caps on a specific process/pg etc.. */
+
+ int capsetp(pid_t pid, cap_t cap_d)
+@@ -78,51 +98,94 @@ int capsetp(pid_t pid, cap_t cap_d)
+
+ _cap_debug("setting process capabilities for proc %d", pid);
+ cap_d->head.pid = pid;
+- error = capset(&cap_d->head, &cap_d->set);
+- cap_d->head.version = _LINUX_CAPABILITY_VERSION_1;
++ error = capset(&cap_d->head, &cap_d->u[0].set);
++ cap_d->head.version = _LIBCAP_CAPABILITY_VERSION;
+ cap_d->head.pid = 0;
+
+ return error;
+ }
+
+-/*
+- * $Log: cap_proc.c,v $
+- * Revision 1.2 2008-08-06 17:00:41 castaglia
+- *
+- * Bug#3096 - libcap version errors on newer Linux kernel. Newer
Linux kernels
+- * have a _LINUX_CAPABILITY_VERSION_2 macro, and redefine the old
+- * _LINUX_CAPABILITY_VERSION macro. To play better with such
kernels, redefine
+- * the bundled libcap to use _LINUX_CAPABILITY_VERSION_1.
+- *
+- * Revision 1.1 2003/01/03 02:16:17 jwm
+- *
+- * Turning mod_linuxprivs into a core module, mod_cap. This is by
no means
+- * complete.
+- *
+- * Revision 1.2 1999/09/07 23:14:19 macgyver
+- * Updated capabilities library and model.
+- *
+- * Revision 1.2 1999/04/18 20:50:01 morgan
+- * reliable behavior when trying to talk with a kernel that has a
more
+- * modern capability implementation than the one the library was
compiled
+- * with.
+- *
+- * Revision 1.1.1.1 1999/04/17 22:16:31 morgan
+- * release 1.0 of libcap
+- *
+- * Revision 1.5 1998/05/24 22:54:09 morgan
+- * updated for 2.1.104
+- *
+- * Revision 1.4 1997/05/14 05:17:13 morgan
+- * bug-fix from zefram (errno no set on success)
+- *
+- * Revision 1.3 1997/05/04 05:35:46 morgan
+- * fixed errno setting. syscalls do this part
+- *
+- * Revision 1.2 1997/04/28 00:57:11 morgan
+- * fixes and zefram's patches
+- *
+- * Revision 1.1 1997/04/21 04:32:52 morgan
+- * Initial revision
+- *
+- */
++/* the kernel api requires unsigned long arguments */
++#define pr_arg(x) ((unsigned long) x)
++
++/* get a capability from the bounding set */
++
++int cap_get_bound(cap_value_t cap)
++{
++ int result;
++
++ result = prctl(PR_CAPBSET_READ, pr_arg(cap));
++ if (result < 0) {
++ errno = -result;
++ return -1;
++ }
++ return result;
++}
++
++/* drop a capability from the bounding set */
++
++int cap_drop_bound(cap_value_t cap)
++{
++ int result;
++
++ result = prctl(PR_CAPBSET_DROP, pr_arg(cap));
++ if (result < 0) {
++ errno = -result;
++ return -1;
++ }
++ return result;
++}
++
++/* get a capability from the ambient set */
++
++int cap_get_ambient(cap_value_t cap)
++{
++ int result;
++ result = prctl(PR_CAP_AMBIENT, pr_arg(PR_CAP_AMBIENT_IS_SET),
++ pr_arg(cap), pr_arg(0), pr_arg(0));
++ if (result < 0) {
++ errno = -result;
++ return -1;
++ }
++ return result;
++}
++
++/* modify a single ambient capability value */
++
++int cap_set_ambient(cap_value_t cap, cap_flag_value_t set)
++{
++ int result, val;
++ switch (set) {
++ case CAP_SET:
++ val = PR_CAP_AMBIENT_RAISE;
++ break;
++ case CAP_CLEAR:
++ val = PR_CAP_AMBIENT_LOWER;
++ break;
++ default:
++ errno = EINVAL;
++ return -1;
++ }
++ result = prctl(PR_CAP_AMBIENT, pr_arg(val), pr_arg(cap),
++ pr_arg(0), pr_arg(0));
++ if (result < 0) {
++ errno = -result;
++ return -1;
++ }
++ return result;
++}
++
++/* erase all ambient capabilities */
++
++int cap_reset_ambient()
++{
++ int result;
++
++ result = prctl(PR_CAP_AMBIENT,
pr_arg(PR_CAP_AMBIENT_CLEAR_ALL),
++ pr_arg(0), pr_arg(0), pr_arg(0));
++ if (result < 0) {
++ errno = -result;
++ return -1;
++ }
++ return result;
++}
+diff --git a/lib/libcap/cap_sys.c b/lib/libcap/cap_sys.c
+deleted file mode 100644
+index 78e64dd..0000000
+--- a/lib/libcap/cap_sys.c
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/*
+- * Copyright (c) 1997-8 Andrew G. Morgan
<[email protected]>
+- *
+- * This file contains the system calls for getting and setting
+- * capabilities
+- */
+-
+-#include "libcap.h"
+-#define __LIBRARY__
+-#include <linux/unistd.h>
+-
+-/*
+- * $Log: cap_sys.c,v $
+- * Revision 1.2 2005-01-25 19:30:55 castaglia
+- *
+- * Bug#2503 - Bundled libcap library does not compile on IA64
machine.
+- *
+- * Revision 1.1 2003/01/03 02:16:17 jwm
+- *
+- * Turning mod_linuxprivs into a core module, mod_cap. This is by
no means
+- * complete.
+- *
+- * Revision 1.3 1999/09/07 23:14:19 macgyver
+- * Updated capabilities library and model.
+- *
+- * Revision 1.1.1.1 1999/04/17 22:16:31 morgan
+- * release 1.0 of libcap
+- *
+- * Revision 1.4 1998/06/08 00:14:01 morgan
+- * change to accommodate alpha (glibc?)
+- *
+- * Revision 1.3 1998/05/24 22:54:09 morgan
+- * updated for 2.1.104
+- *
+- * Revision 1.2 1997/04/28 00:57:11 morgan
+- * fixes and zefram's patches
+- *
+- * Revision 1.1 1997/04/21 04:32:52 morgan
+- * Initial revision
+- *
+- */
+diff --git a/lib/libcap/cap_text.c b/lib/libcap/cap_text.c
+index 11f4e48..42fb685 100644
+--- a/lib/libcap/cap_text.c
++++ b/lib/libcap/cap_text.c
+@@ -1,45 +1,43 @@
+ /*
+- * Copyright (c) 1997-8 Andrew G Morgan <[email protected]>
++ * Copyright (c) 1997-8,2007-8 Andrew G Morgan <[email protected]>
+ * Copyright (c) 1997 Andrew Main <[email protected]>
+ *
+- * See end of file for Log.
+- *
+ * This file deals with exchanging internal and textual
+ * representations of capability sets.
+ */
+
++#define _GNU_SOURCE
++#include <stdio.h>
++
+ #define LIBCAP_PLEASE_INCLUDE_ARRAY
+ #include "libcap.h"
+
+ #include <ctype.h>
+-#include <stdio.h>
++#include <limits.h>
+
+ /* Maximum output text length (16 per cap) */
+-#define CAP_TEXT_SIZE (16*__CAP_BITS)
+-
+-#define LIBCAP_EFF 01
+-#define LIBCAP_INH 02
+-#define LIBCAP_PER 04
++#define CAP_TEXT_SIZE (16*__CAP_MAXBITS)
+
+ /*
+ * Parse a textual representation of capabilities, returning an
internal
+ * representation.
+ */
+
+-#define setbits(A,B) _setbits((__cap_s *)A, (__cap_s *)B)
+-static void _setbits(__cap_s *a, __cap_s *b)
++#define raise_cap_mask(flat, c) (flat)[CAP_TO_INDEX(c)] |=
CAP_TO_MASK(c)
++
++static void setbits(cap_t a, const __u32 *b, cap_flag_t set,
unsigned blks)
+ {
+ int n;
+- for (n = __CAP_BLKS; n--; )
+- a->_blk[n] |= b->_blk[n];
++ for (n = blks; n--; ) {
++ a->u[n].flat[set] |= b[n];
++ }
+ }
+
+-#define clrbits(A,B) _clrbits((__cap_s *)A, (__cap_s *)B)
+-static void _clrbits(__cap_s *a, __cap_s *b)
++static void clrbits(cap_t a, const __u32 *b, cap_flag_t set,
unsigned blks)
+ {
+ int n;
+- for (n = __CAP_BLKS; n--; )
+- a->_blk[n] &= ~b->_blk[n];
++ for (n = blks; n--; )
++ a->u[n].flat[set] &= ~b[n];
+ }
+
+ static char const *namcmp(char const *str, char const *nam)
+@@ -53,32 +51,67 @@ static char const *namcmp(char const *str, char
const *nam)
+ return str;
+ }
+
++static void forceall(__u32 *flat, __u32 value, unsigned blks)
++{
++ unsigned n;
++
++ for (n = blks; n--; flat[n] = value);
++
++ return;
++}
++
+ static int lookupname(char const **strp)
+ {
+- char const *str = *strp;
+- if (isdigit(*str)) {
+- unsigned long n = strtoul(str, (char **)&str, 0);
+- if (n >= __CAP_BITS)
++ union {
++ char const *constp;
++ char *p;
++ } str;
++
++ str.constp = *strp;
++ if (isdigit(*str.constp)) {
++ unsigned long n = strtoul(str.constp, &str.p, 0);
++ if (n >= __CAP_MAXBITS)
+ return -1;
+- *strp = str;
++ *strp = str.constp;
+ return n;
+ } else {
++ int c;
++ unsigned len;
++
++ for (len=0; (c = str.constp[len]); ++len) {
++ if (!(isalpha(c) || (c == '_'))) {
++ break;
++ }
++ }
++
++#ifdef GPERF_DOWNCASE
++ const struct __cap_token_s *token_info;
++
++ token_info = __cap_lookup_name(str.constp, len);
++ if (token_info != NULL) {
++ *strp = str.constp + len;
++ return token_info->index;
++ }
++#else /* ie., ndef GPERF_DOWNCASE */
+ char const *s;
+- int n;
++ unsigned n;
++
+ for (n = __CAP_BITS; n--; )
+- if (_cap_names[n] && (s = namcmp(str, _cap_names[n]))) {
++ if (_cap_names[n] && (s = namcmp(str.constp,
_cap_names[n]))) {
+ *strp = s;
+ return n;
+ }
+- return -1;
++#endif /* def GPERF_DOWNCASE */
++
++ return -1; /* No definition available */
+ }
+ }
+
+ cap_t cap_from_text(const char *str)
+ {
+ cap_t res;
+- __cap_s allones;
+ int n;
++ unsigned cap_blks;
+
+ if (str == NULL) {
+ _cap_debug("bad argument");
+@@ -88,22 +121,39 @@ cap_t cap_from_text(const char *str)
+
+ if (!(res = cap_init()))
+ return NULL;
+- for (n = __CAP_BLKS; n--; )
+- allones._blk[n] = -1;
++
++ switch (res->head.version) {
++ case _LINUX_CAPABILITY_VERSION_1:
++ cap_blks = _LINUX_CAPABILITY_U32S_1;
++ break;
++ case _LINUX_CAPABILITY_VERSION_2:
++ cap_blks = _LINUX_CAPABILITY_U32S_2;
++ break;
++ case _LINUX_CAPABILITY_VERSION_3:
++ cap_blks = _LINUX_CAPABILITY_U32S_3;
++ break;
++ default:
++ errno = EINVAL;
++ return NULL;
++ }
++
+ _cap_debug("%s", str);
+
+ for (;;) {
++ __u32 list[__CAP_BLKS];
+ char op;
+ int flags = 0, listed=0;
+- __cap_s list = {{0}};
++
++ forceall(list, 0, __CAP_BLKS);
+
+ /* skip leading spaces */
+ while (isspace((unsigned char)*str))
+ str++;
+ if (!*str) {
+- _cap_debugcap("e = ", &res->set.effective);
+- _cap_debugcap("i = ", &res->set.inheritable);
+- _cap_debugcap("p = ", &res->set.permitted);
++ _cap_debugcap("e = ", *res, CAP_EFFECTIVE);
++ _cap_debugcap("i = ", *res, CAP_INHERITABLE);
++ _cap_debugcap("p = ", *res, CAP_PERMITTED);
++
+ return res;
+ }
+
+@@ -112,12 +162,12 @@ cap_t cap_from_text(const char *str)
+ for (;;) {
+ if (namcmp(str, "all")) {
+ str += 3;
+- list = allones;
++ forceall(list, ~0, cap_blks);
+ } else {
+ n = lookupname(&str);
+ if (n == -1)
+ goto bad;
+- list.raise_cap(n);
++ raise_cap_mask(list, n);
+ }
+ if (*str != ',')
+ break;
+@@ -125,10 +175,11 @@ cap_t cap_from_text(const char *str)
+ goto bad;
+ }
+ listed = 1;
+- } else if (*str == '+' || *str == '-')
++ } else if (*str == '+' || *str == '-') {
+ goto bad; /* require a list of
capabilities */
+- else
+- list = allones;
++ } else {
++ forceall(list, ~0, cap_blks);
++ }
+
+ /* identify first operation on list of capabilities */
+ op = *str++;
+@@ -166,28 +217,28 @@ cap_t cap_from_text(const char *str)
+ case '=':
+ case 'P':
/* =+ */
+ case 'M':
/* =- */
+- clrbits(&res->set.effective, &list);
+- clrbits(&res->set.inheritable, &list);
+- clrbits(&res->set.permitted, &list);
+- /* fall through */
++ clrbits(res, list, CAP_EFFECTIVE, cap_blks);
++ clrbits(res, list, CAP_PERMITTED, cap_blks);
++ clrbits(res, list, CAP_INHERITABLE, cap_blks);
+ if (op == 'M')
+ goto minus;
++ /* fall through */
+ case '+':
+ if (flags & LIBCAP_EFF)
+- setbits(&res->set.effective, &list);
+- if (flags & LIBCAP_INH)
+- setbits(&res->set.inheritable, &list);
++ setbits(res, list, CAP_EFFECTIVE, cap_blks);
+ if (flags & LIBCAP_PER)
+- setbits(&res->set.permitted, &list);
++ setbits(res, list, CAP_PERMITTED, cap_blks);
++ if (flags & LIBCAP_INH)
++ setbits(res, list, CAP_INHERITABLE, cap_blks);
+ break;
+ case '-':
+ minus:
+- if (flags & LIBCAP_EFF)
+- clrbits(&res->set.effective, &list);
+- if (flags & LIBCAP_INH)
+- clrbits(&res->set.inheritable, &list);
++ if (flags & LIBCAP_EFF)
++ clrbits(res, list, CAP_EFFECTIVE, cap_blks);
+ if (flags & LIBCAP_PER)
+- clrbits(&res->set.permitted, &list);
++ clrbits(res, list, CAP_PERMITTED, cap_blks);
++ if (flags & LIBCAP_INH)
++ clrbits(res, list, CAP_INHERITABLE, cap_blks);
+ break;
+ }
+
+@@ -207,9 +258,44 @@ cap_t cap_from_text(const char *str)
+ }
+
+ bad:
+- cap_free(&res);
++ cap_free(res);
++ res = NULL;
+ errno = EINVAL;
+- return NULL;
++ return res;
++}
++
++/*
++ * lookup a capability name and return its numerical value
++ */
++int cap_from_name(const char *name, cap_value_t *value_p)
++{
++ int n;
++
++ if (((n = lookupname(&name)) >= 0) && (value_p != NULL)) {
++ *value_p = (unsigned) n;
++ }
++ return -(n < 0);
++}
++
++/*
++ * Convert a single capability index number into a string
representation
++ */
++char *cap_to_name(cap_value_t cap)
++{
++ if ((cap < 0) || (cap >= __CAP_BITS)) {
++#if UINT_MAX != 4294967295U
++# error Recompile with correctly sized numeric array
++#endif
++ char *tmp, *result;
++
++ asprintf(&tmp, "%u", cap);
++ result = _libcap_strdup(tmp);
++ free(tmp);
++
++ return result;
++ } else {
++ return _libcap_strdup(_cap_names[cap]);
++ }
+ }
+
+ /*
+@@ -222,12 +308,15 @@ static int getstateflags(cap_t caps, int
capno)
+ {
+ int f = 0;
+
+- if (isset_cap((__cap_s *)(&caps->set.effective),capno))
++ if (isset_cap(caps, capno, CAP_EFFECTIVE)) {
+ f |= LIBCAP_EFF;
+- if (isset_cap((__cap_s *)(&caps->set.inheritable),capno))
+- f |= LIBCAP_INH;
+- if (isset_cap((__cap_s *)(&caps->set.permitted),capno))
++ }
++ if (isset_cap(caps, capno, CAP_PERMITTED)) {
+ f |= LIBCAP_PER;
++ }
++ if (isset_cap(caps, capno, CAP_INHERITABLE)) {
++ f |= LIBCAP_INH;
++ }
+
+ return f;
+ }
+@@ -236,10 +325,12 @@ static int getstateflags(cap_t caps, int
capno)
+
+ char *cap_to_text(cap_t caps, ssize_t *length_p)
+ {
+- static char buf[CAP_TEXT_SIZE+CAP_TEXT_BUFFER_ZONE];
++ char buf[CAP_TEXT_SIZE+CAP_TEXT_BUFFER_ZONE];
+ char *p;
+- int histo[8] = {0};
+- int m, n, t;
++ int histo[8];
++ int m, t;
++ unsigned n;
++ unsigned cap_maxbits, cap_blks;
+
+ /* Check arguments */
+ if (!good_cap_t(caps)) {
+@@ -247,17 +338,47 @@ char *cap_to_text(cap_t caps, ssize_t
*length_p)
+ return NULL;
+ }
+
+- _cap_debugcap("e = ", &caps->set.effective);
+- _cap_debugcap("i = ", &caps->set.inheritable);
+- _cap_debugcap("p = ", &caps->set.permitted);
++ switch (caps->head.version) {
++ case _LINUX_CAPABILITY_VERSION_1:
++ cap_blks = _LINUX_CAPABILITY_U32S_1;
++ break;
++ case _LINUX_CAPABILITY_VERSION_2:
++ cap_blks = _LINUX_CAPABILITY_U32S_2;
++ break;
++ case _LINUX_CAPABILITY_VERSION_3:
++ cap_blks = _LINUX_CAPABILITY_U32S_3;
++ break;
++ default:
++ errno = EINVAL;
++ return NULL;
++ }
++
++ cap_maxbits = 32 * cap_blks;
+
+- for (n = __CAP_BITS; n--; )
++ _cap_debugcap("e = ", *caps, CAP_EFFECTIVE);
++ _cap_debugcap("i = ", *caps, CAP_INHERITABLE);
++ _cap_debugcap("p = ", *caps, CAP_PERMITTED);
++
++ memset(histo, 0, sizeof(histo));
++
++ /* default prevailing state to the upper - unnamed bits */
++ for (n = cap_maxbits-1; n > __CAP_BITS; n--)
+ histo[getstateflags(caps, n)]++;
+
++ /* find which combination of capability sets shares the most
bits
++ we bias to preferring non-set (m=0) with the >= 0 test.
Failing
++ to do this causes strange things to happen with older
systems
++ that don't know about bits 32+. */
+ for (m=t=7; t--; )
+- if (histo[t] > histo[m])
++ if (histo[t] >= histo[m])
+ m = t;
+
++ /* capture remaining bits - selecting m from only the unnamed
bits,
++ we maximize the likelihood that we won't see numeric
capability
++ values in the text output. */
++ while (n--)
++ histo[getstateflags(caps, n)]++;
++
+ /* blank is not a valid capability set */
+ p = sprintf(buf, "=%s%s%s",
+ (m & LIBCAP_EFF) ? "e" : "",
+@@ -267,16 +388,18 @@ char *cap_to_text(cap_t caps, ssize_t
*length_p)
+ for (t = 8; t--; )
+ if (t != m && histo[t]) {
+ *p++ = ' ';
+- for (n = 0; n != __CAP_BITS; n++)
++ for (n = 0; n < cap_maxbits; n++)
+ if (getstateflags(caps, n) == t) {
+- if (_cap_names[n])
+- p += sprintf(p, "%s,", _cap_names[n]);
+- else
+- p += sprintf(p, "%d,", n);
+- if (p - buf > CAP_TEXT_SIZE) {
++ char *this_cap_name;
++
++ this_cap_name = cap_to_name(n);
++ if ((strlen(this_cap_name) + (p - buf)) >
CAP_TEXT_SIZE) {
++ cap_free(this_cap_name);
+ errno = ERANGE;
+ return NULL;
+ }
++ p += sprintf(p, "%s,", this_cap_name);
++ cap_free(this_cap_name);
+ }
+ p--;
+ n = t & ~m;
+@@ -304,41 +427,3 @@ char *cap_to_text(cap_t caps, ssize_t
*length_p)
+
+ return (_libcap_strdup(buf));
+ }
+-
+-/*
+- * $Log: cap_text.c,v $
+- * Revision 1.2 2003-05-15 00:49:13 castaglia
+- *
+- * Bug#2000 - mod_cap should not use bundled libcap. This patch
updates the
+- * bundled libcap; I won't be closing the bug report just yet.
+- *
+- * Revision 1.1 2003/01/03 02:16:17 jwm
+- *
+- * Turning mod_linuxprivs into a core module, mod_cap. This is by
no means
+- * complete.
+- *
+- * Revision 1.3 2000/07/11 13:36:52 macgyver
+- * Minor updates and buffer cleanups.
+- *
+- * Revision 1.2 1999/09/07 23:14:19 macgyver
+- * Updated capabilities library and model.
+- *
+- * Revision 1.2 1999/04/17 23:25:09 morgan
+- * fixes from peeterj
+- *
+- * Revision 1.1.1.1 1999/04/17 22:16:31 morgan
+- * release 1.0 of libcap
+- *
+- * Revision 1.4 1998/05/24 22:54:09 morgan
+- * updated for 2.1.104
+- *
+- * Revision 1.3 1997/05/04 05:37:00 morgan
+- * case sensitvity to capability flags
+- *
+- * Revision 1.2 1997/04/28 00:57:11 morgan
+- * zefram's replacement file with a number of bug fixes from AGM
+- *
+- * Revision 1.1 1997/04/21 04:32:52 morgan
+- * Initial revision
+- *
+- */
+diff --git a/lib/libcap/include/sys/capability.h
b/lib/libcap/include/sys/capability.h
+index 6a4ef4a..0976fa7 100644
+--- a/lib/libcap/include/sys/capability.h
++++ b/lib/libcap/include/sys/capability.h
+@@ -1,9 +1,8 @@
+ /*
+ * <sys/capability.h>
+ *
+- *
+ * Copyright (C) 1997 Aleph One
+- * Copyright (C) 1997-8 Andrew G. Morgan <[email protected]>
++ * Copyright (C) 1997-8,2008 Andrew G. Morgan <[email protected]>
+ *
+ * defunct POSIX.1e Standard: 25.2 Capabilities
<sys/capability.h>
+ */
+@@ -20,8 +19,13 @@ extern "C" {
+ * information for the user library.
+ */
+
+-#define _LINUX_FS_H
+ #include <sys/types.h>
++#include <stdint.h>
++#include <linux/types.h>
++
++#ifndef __user
++#define __user
++#endif
+ #include <linux/capability.h>
+
+ /*
+@@ -64,48 +68,60 @@ typedef enum {
+ */
+
+ /* libcap/cap_alloc.c */
+-cap_t cap_dup(cap_t);
+-int cap_free(void *);
+-cap_t cap_init(void);
++extern cap_t cap_dup(cap_t);
++extern int cap_free(void *);
++extern cap_t cap_init(void);
+
+ /* libcap/cap_flag.c */
+-int cap_get_flag(cap_t, cap_value_t, cap_flag_t,
cap_flag_value_t *);
+-int cap_set_flag(cap_t, cap_flag_t, int, cap_value_t *,
cap_flag_value_t);
+-int cap_clear(cap_t);
++extern int cap_get_flag(cap_t, cap_value_t, cap_flag_t,
cap_flag_value_t *);
++extern int cap_set_flag(cap_t, cap_flag_t, int, const
cap_value_t *,
++ cap_flag_value_t);
++extern int cap_clear(cap_t);
++extern int cap_clear_flag(cap_t, cap_flag_t);
+
+ /* libcap/cap_file.c */
+-cap_t cap_get_fd(int);
+-cap_t cap_get_file(const char *);
+-int cap_set_fd(int, cap_t);
+-int cap_set_file(const char *, cap_t);
++extern cap_t cap_get_fd(int);
++extern cap_t cap_get_file(const char *);
++extern int cap_set_fd(int, cap_t);
++extern int cap_set_file(const char *, cap_t);
+
+ /* libcap/cap_proc.c */
+-cap_t cap_get_proc(void);
+-int cap_set_proc(cap_t);
++extern cap_t cap_get_proc(void);
++extern cap_t cap_get_pid(pid_t);
++extern int cap_set_proc(cap_t);
++
++extern int cap_get_bound(cap_value_t);
++extern int cap_drop_bound(cap_value_t);
++#define CAP_IS_SUPPORTED(cap) (cap_get_bound(cap) >= 0)
++
++extern int cap_get_ambient(cap_value_t);
++extern int cap_set_ambient(cap_value_t, cap_flag_value_t);
++extern int cap_reset_ambient(void);
++#define CAP_AMBIENT_SUPPORTED() (cap_get_ambient(CAP_CHOWN) >= 0)
+
+ /* libcap/cap_extint.c */
+-ssize_t cap_size(cap_t);
+-ssize_t cap_copy_ext(void *, cap_t, ssize_t);
+-cap_t cap_copy_int(const void *);
++extern ssize_t cap_size(cap_t);
++extern ssize_t cap_copy_ext(void *, cap_t, ssize_t);
++extern cap_t cap_copy_int(const void *);
+
+ /* libcap/cap_text.c */
+-cap_t cap_from_text(const char *);
+-char * cap_to_text(cap_t, ssize_t *);
+-
+-/*
+- * Linux capability system calls: defined in libcap but only
available
+- * if the following _POSIX_SOURCE is _undefined_
+- */
++extern cap_t cap_from_text(const char *);
++extern char * cap_to_text(cap_t, ssize_t *);
++extern int cap_from_name(const char *, cap_value_t *);
++extern char * cap_to_name(cap_value_t);
+
+-#if !defined(_POSIX_SOURCE)
++#define CAP_DIFFERS(result, flag) (((result) & (1 << (flag))) !=
0)
++extern int cap_compare(cap_t, cap_t);
+
++/* system calls - look to libc for function to system call mapping
*/
+ extern int capset(cap_user_header_t header, cap_user_data_t data);
+ extern int capget(cap_user_header_t header, const cap_user_data_t
data);
++
++/* deprecated - use cap_get_pid() */
+ extern int capgetp(pid_t pid, cap_t cap_d);
+-extern int capsetp(pid_t pid, cap_t cap_d);
+-extern char const *_cap_names[];
+
+-#endif /* !defined(_POSIX_SOURCE) */
++/* not valid with filesystem capability support - use
cap_set_proc() */
++extern int capsetp(pid_t pid, cap_t cap_d);
+
+ #ifdef __cplusplus
+ }
+diff --git a/lib/libcap/include/sys/securebits.h
b/lib/libcap/include/sys/securebits.h
+new file mode 100644
+index 0000000..14cf3c5
+--- /dev/null
++++ b/lib/libcap/include/sys/securebits.h
+@@ -0,0 +1,22 @@
++/*
++ * <sys/securebits.h>
++ * Copyright (C) 2010 Serge Hallyn <[email protected]>
++ */
++
++#ifndef _SYS_SECUREBITS_H
++#define _SYS_SECUREBITS_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#ifndef __user
++#define __user
++#endif
++#include <linux/securebits.h>
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _SYS_SECUREBITS_H */
+diff --git a/lib/libcap/include/uapi/linux/capability.h
b/lib/libcap/include/uapi/linux/capability.h
+new file mode 100644
+index 0000000..432e023
+--- /dev/null
++++ b/lib/libcap/include/uapi/linux/capability.h
+@@ -0,0 +1,367 @@
++/*
++ * This is <linux/capability.h>
++ *
++ * Andrew G. Morgan <[email protected]>
++ * Alexander Kjeldaas <[email protected]>
++ * with help from Aleph1, Roland Buresund and Andrew Main.
++ *
++ * See here for the libcap library ("POSIX draft" compliance):
++ *
++ * http://www.kernel.org/pub/linux/libs/security/linux-privs/
++ */
++
++#ifndef _UAPI_LINUX_CAPABILITY_H
++#define _UAPI_LINUX_CAPABILITY_H
++
++#include <linux/types.h>
++
++struct task_struct;
++
++/* User-level do most of the mapping between kernel and user
++ capabilities based on the version tag given by the kernel. The
++ kernel might be somewhat backwards compatible, but don't bet on
++ it. */
++
++/* 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_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;
++ int pid;
++} __user *cap_user_header_t;
++
++typedef struct __user_cap_data_struct {
++ __u32 effective;
++ __u32 permitted;
++ __u32 inheritable;
++} __user *cap_user_data_t;
++
++
++#define VFS_CAP_REVISION_MASK 0xFF000000
++#define VFS_CAP_REVISION_SHIFT 24
++#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_2 0x02000000
++#define VFS_CAP_U32_2 2
++#define XATTR_CAPS_SZ_2 (sizeof(__le32)*(1 +
2*VFS_CAP_U32_2))
++
++#define XATTR_CAPS_SZ XATTR_CAPS_SZ_2
++#define VFS_CAP_U32 VFS_CAP_U32_2
++#define VFS_CAP_REVISION VFS_CAP_REVISION_2
++
++struct vfs_cap_data {
++ __le32 magic_etc; /* Little endian */
++ struct {
++ __le32 permitted; /* Little endian */
++ __le32 inheritable; /* Little endian */
++ } data[VFS_CAP_U32];
++};
++
++#ifndef __KERNEL__
++
++/*
++ * 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
++
++#endif
++
++
++/**
++ ** POSIX-draft defined capabilities.
++ **/
++
++/* In a system with the [_POSIX_CHOWN_RESTRICTED] option defined,
this
++ overrides the restriction of changing file ownership and group
++ ownership. */
++
++#define CAP_CHOWN 0
++
++/* Override all DAC access, including ACL execute access if
++ [_POSIX_ACL] is defined. Excluding DAC access covered by
++ CAP_LINUX_IMMUTABLE. */
++
++#define CAP_DAC_OVERRIDE 1
++
++/* Overrides all DAC restrictions regarding read and search on
files
++ and directories, including ACL restrictions if [_POSIX_ACL] is
++ defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */
++
++#define CAP_DAC_READ_SEARCH 2
++
++/* Overrides all restrictions about allowed operations on files,
where
++ file owner ID must be equal to the user ID, except where
CAP_FSETID
++ is applicable. It doesn't override MAC and DAC restrictions. */
++
++#define CAP_FOWNER 3
++
++/* Overrides the following restrictions that the effective user ID
++ shall match the file owner ID when setting the S_ISUID and
S_ISGID
++ bits on that file; that the effective group ID (or one of the
++ supplementary group IDs) shall match the file owner ID when
setting
++ the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits
are
++ cleared on successful return from chown(2) (not implemented). */
++
++#define CAP_FSETID 4
++
++/* 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. */
++
++#define CAP_KILL 5
++
++/* Allows setgid(2) manipulation */
++/* Allows setgroups(2) */
++/* Allows forged gids on socket credentials passing. */
++
++#define CAP_SETGID 6
++
++/* Allows set*uid(2) manipulation (including fsuid). */
++/* Allows forged pids on socket credentials passing. */
++
++#define CAP_SETUID 7
++
++
++/**
++ ** Linux-specific capabilities
++ **/
++
++/* 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
++
++/* Allow modification of S_IMMUTABLE and S_APPEND file attributes
*/
++
++#define CAP_LINUX_IMMUTABLE 9
++
++/* Allows binding to TCP/UDP sockets below 1024 */
++/* Allows binding to ATM VCIs below 32 */
++
++#define CAP_NET_BIND_SERVICE 10
++
++/* Allow broadcasting, listen to multicast */
++
++#define CAP_NET_BROADCAST 11
++
++/* Allow interface configuration */
++/* Allow administration of IP firewall, masquerading and accounting
*/
++/* Allow setting debug option on sockets */
++/* Allow modification of routing tables */
++/* Allow setting arbitrary process / process group ownership on
++ sockets */
++/* 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 */
++/* Allow multicasting */
++/* Allow read/write of device-specific registers */
++/* Allow activation of ATM control sockets */
++
++#define CAP_NET_ADMIN 12
++
++/* 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
++
++/* Allow locking of shared memory segments */
++/* Allow mlock and mlockall (which doesn't really have anything to
do
++ with IPC) */
++
++#define CAP_IPC_LOCK 14
++
++/* Override IPC ownership checks */
++
++#define CAP_IPC_OWNER 15
++
++/* Insert and remove kernel modules - modify kernel without limit
*/
++#define CAP_SYS_MODULE 16
++
++/* Allow ioperm/iopl access */
++/* Allow sending USB messages to any device via /proc/bus/usb */
++
++#define CAP_SYS_RAWIO 17
++
++/* Allow use of chroot() */
++
++#define CAP_SYS_CHROOT 18
++
++/* Allow ptrace() of any process */
++
++#define CAP_SYS_PTRACE 19
++
++/* Allow configuration of process accounting */
++
++#define CAP_SYS_PACCT 20
++
++/* Allow configuration of the secure attention key */
++/* Allow administration of the random device */
++/* Allow examination and configuration of disk quotas */
++/* Allow setting the domainname */
++/* Allow setting the hostname */
++/* Allow calling bdflush() */
++/* Allow mount() and umount(), setting up new smb connection */
++/* Allow some autofs root ioctls */
++/* Allow nfsservctl */
++/* Allow VM86_REQUEST_IRQ */
++/* Allow to read/write pci config on alpha */
++/* Allow irix_prctl on mips (setstacksize) */
++/* Allow flushing all cache on m68k (sys_cacheflush) */
++/* Allow removing semaphores */
++/* Used instead of CAP_CHOWN to "chown" IPC message queues,
semaphores
++ and shared memory */
++/* Allow locking/unlocking of shared memory segment */
++/* Allow turning swap on/off */
++/* Allow forged pids on socket credentials passing */
++/* Allow setting readahead and flushing buffers on block devices */
++/* Allow setting geometry in floppy driver */
++/* Allow turning DMA on/off in xd driver */
++/* Allow administration of md devices (mostly the above, but some
++ extra ioctls) */
++/* Allow tuning the ide driver */
++/* Allow access to the nvram device */
++/* Allow administration of apm_bios, serial and bttv (TV) device */
++/* Allow manufacturer commands in isdn CAPI support driver */
++/* Allow reading non-standardized portions of pci configuration
space */
++/* Allow DDI debug ioctl on sbpcd driver */
++/* Allow setting up serial ports */
++/* Allow sending raw qic-117 commands */
++/* Allow enabling/disabling tagged queuing on SCSI controllers and
sending
++ arbitrary SCSI commands */
++/* Allow setting encryption key on loopback filesystem */
++/* Allow setting zone reclaim policy */
++
++#define CAP_SYS_ADMIN 21
++
++/* Allow use of reboot() */
++
++#define CAP_SYS_BOOT 22
++
++/* Allow raising priority and setting priority on other (different
++ UID) processes */
++/* Allow use of FIFO and round-robin (realtime) scheduling on own
++ processes and setting the scheduling algorithm used by another
++ process. */
++/* Allow setting cpu affinity on other processes */
++
++#define CAP_SYS_NICE 23
++
++/* Override resource limits. Set resource limits. */
++/* Override quota limits. */
++/* Override reserved space on ext2 filesystem */
++/* Modify data journaling mode on ext3 filesystem (uses journaling
++ resources) */
++/* NOTE: ext2 honors fsuid when checking for resource overrides, so
++ you can override using fsuid too */
++/* Override size restrictions on IPC message queues */
++/* Allow more than 64hz interrupts from the real-time clock */
++/* Override max number of consoles on console allocation */
++/* Override max number of keymaps */
++
++#define CAP_SYS_RESOURCE 24
++
++/* Allow manipulation of system clock */
++/* Allow irix_stime on mips */
++/* Allow setting the real-time clock */
++
++#define CAP_SYS_TIME 25
++
++/* Allow configuration of tty devices */
++/* Allow vhangup() of tty */
++
++#define CAP_SYS_TTY_CONFIG 26
++
++/* Allow the privileged aspects of mknod() */
++
++#define CAP_MKNOD 27
++
++/* Allow taking of leases on files */
++
++#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
++
++/* 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
++
++/* Allow configuring the kernel's syslog (printk behaviour) */
++
++#define CAP_SYSLOG 34
++
++/* Allow triggering something that will wake the system */
++
++#define CAP_WAKE_ALARM 35
++
++/* Allow preventing system suspends */
++
++#define CAP_BLOCK_SUSPEND 36
++
++/* 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)
++
++/*
++ * 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 */
++
++
++#endif /* _UAPI_LINUX_CAPABILITY_H */
+diff --git a/lib/libcap/include/uapi/linux/prctl.h
b/lib/libcap/include/uapi/linux/prctl.h
+new file mode 100644
+index 0000000..a8d0759
+--- /dev/null
++++ b/lib/libcap/include/uapi/linux/prctl.h
+@@ -0,0 +1,200 @@
++#ifndef _LINUX_PRCTL_H
++#define _LINUX_PRCTL_H
++
++#include <linux/types.h>
++
++/* Values to pass as first argument to prctl() */
++
++#define PR_SET_PDEATHSIG 1 /* Second arg is a signal */
++#define PR_GET_PDEATHSIG 2 /* Second arg is a ptr to return the
signal */
++
++/* Get/set current->mm->dumpable */
++#define PR_GET_DUMPABLE 3
++#define PR_SET_DUMPABLE 4
++
++/* Get/set unaligned access control bits (if meaningful) */
++#define PR_GET_UNALIGN 5
++#define PR_SET_UNALIGN 6
++# define PR_UNALIGN_NOPRINT 1 /* silently fix up unaligned
user accesses */
++# define PR_UNALIGN_SIGBUS 2 /* generate SIGBUS on
unaligned user access */
++
++/* Get/set whether or not to drop capabilities on setuid() away
from
++ * uid 0 (as per security/commoncap.c) */
++#define PR_GET_KEEPCAPS 7
++#define PR_SET_KEEPCAPS 8
++
++/* Get/set floating-point emulation control bits (if meaningful) */
++#define PR_GET_FPEMU 9
++#define PR_SET_FPEMU 10
++# define PR_FPEMU_NOPRINT 1 /* silently emulate fp
operations accesses */
++# define PR_FPEMU_SIGFPE 2 /* don't emulate fp
operations, send SIGFPE instead */
++
++/* Get/set floating-point exception mode (if meaningful) */
++#define PR_GET_FPEXC 11
++#define PR_SET_FPEXC 12
++# define PR_FP_EXC_SW_ENABLE 0x80 /* Use FPEXC for FP
exception enables */
++# define PR_FP_EXC_DIV 0x010000 /* floating
point divide by zero */
++# define PR_FP_EXC_OVF 0x020000 /* floating
point overflow */
++# define PR_FP_EXC_UND 0x040000 /* floating
point underflow */
++# define PR_FP_EXC_RES 0x080000 /* floating
point inexact result */
++# define PR_FP_EXC_INV 0x100000 /* floating
point invalid operation */
++# define PR_FP_EXC_DISABLED 0 /* FP exceptions disabled */
++# define PR_FP_EXC_NONRECOV 1 /* async non-recoverable
exc. mode */
++# define PR_FP_EXC_ASYNC 2 /* async recoverable
exception mode */
++# define PR_FP_EXC_PRECISE 3 /* precise exception mode */
++
++/* Get/set whether we use statistical process timing or accurate
timestamp
++ * based process timing */
++#define PR_GET_TIMING 13
++#define PR_SET_TIMING 14
++# define PR_TIMING_STATISTICAL 0 /* Normal, traditional,
++ statistical
process timing */
++# define PR_TIMING_TIMESTAMP 1 /* Accurate timestamp based
++ process timing
*/
++
++#define PR_SET_NAME 15 /* Set process name */
++#define PR_GET_NAME 16 /* Get process name */
++
++/* Get/set process endian */
++#define PR_GET_ENDIAN 19
++#define PR_SET_ENDIAN 20
++# define PR_ENDIAN_BIG 0
++# define PR_ENDIAN_LITTLE 1 /* True little endian mode
*/
++# define PR_ENDIAN_PPC_LITTLE 2 /* "PowerPC" pseudo little
endian */
++
++/* Get/set process seccomp mode */
++#define PR_GET_SECCOMP 21
++#define PR_SET_SECCOMP 22
++
++/* Get/set the capability bounding set (as per
security/commoncap.c) */
++#define PR_CAPBSET_READ 23
++#define PR_CAPBSET_DROP 24
++
++/* Get/set the process' ability to use the timestamp counter
instruction */
++#define PR_GET_TSC 25
++#define PR_SET_TSC 26
++# define PR_TSC_ENABLE 1 /* allow the use of
the timestamp counter */
++# define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV
instead of reading the TSC */
++
++/* Get/set securebits (as per security/commoncap.c) */
++#define PR_GET_SECUREBITS 27
++#define PR_SET_SECUREBITS 28
++
++/*
++ * Get/set the timerslack as used by poll/select/nanosleep
++ * A value of 0 means "use default"
++ */
++#define PR_SET_TIMERSLACK 29
++#define PR_GET_TIMERSLACK 30
++
++#define PR_TASK_PERF_EVENTS_DISABLE 31
++#define PR_TASK_PERF_EVENTS_ENABLE 32
++
++/*
++ * Set early/late kill mode for hwpoison memory corruption.
++ * This influences when the process gets killed on a memory
corruption.
++ */
++#define PR_MCE_KILL 33
++# define PR_MCE_KILL_CLEAR 0
++# define PR_MCE_KILL_SET 1
++
++# define PR_MCE_KILL_LATE 0
++# define PR_MCE_KILL_EARLY 1
++# define PR_MCE_KILL_DEFAULT 2
++
++#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
++# define PR_SET_MM_MAP 14
++# define PR_SET_MM_MAP_SIZE 15
++
++/*
++ * This structure provides new memory descriptor
++ * map which mostly modifies /proc/pid/stat[m]
++ * output for a task. This mostly done in a
++ * sake of checkpoint/restore functionality.
++ */
++struct prctl_mm_map {
++ __u64 start_code; /* code section bounds */
++ __u64 end_code;
++ __u64 start_data; /* data section bounds */
++ __u64 end_data;
++ __u64 start_brk; /* heap for brk() syscall */
++ __u64 brk;
++ __u64 start_stack; /* stack starts at */
++ __u64 arg_start; /* command line arguments
bounds */
++ __u64 arg_end;
++ __u64 env_start; /* environment variables
bounds */
++ __u64 env_end;
++ __u64 *auxv; /* auxiliary vector */
++ __u32 auxv_size; /* vector size */
++ __u32 exe_fd; /* /proc/$pid/exe
link file */
++};
++
++/*
++ * 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
++
++#define PR_SET_THP_DISABLE 41
++#define PR_GET_THP_DISABLE 42
++
++/*
++ * Tell the kernel to start/stop helping userspace manage bounds
tables.
++ */
++#define PR_MPX_ENABLE_MANAGEMENT 43
++#define PR_MPX_DISABLE_MANAGEMENT 44
++
++#define PR_SET_FP_MODE 45
++#define PR_GET_FP_MODE 46
++# define PR_FP_MODE_FR (1 << 0) /* 64b FP
registers */
++# define PR_FP_MODE_FRE (1 << 1) /* 32b
compatibility */
++
++/* Control the ambient capability set */
++#define PR_CAP_AMBIENT 47
++# define PR_CAP_AMBIENT_IS_SET 1
++# define PR_CAP_AMBIENT_RAISE 2
++# define PR_CAP_AMBIENT_LOWER 3
++# define PR_CAP_AMBIENT_CLEAR_ALL 4
++
++#endif /* _LINUX_PRCTL_H */
+diff --git a/lib/libcap/include/uapi/linux/securebits.h
b/lib/libcap/include/uapi/linux/securebits.h
+new file mode 100644
+index 0000000..35ac35c
+--- /dev/null
++++ b/lib/libcap/include/uapi/linux/securebits.h
+@@ -0,0 +1,60 @@
++#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))
++
++#define SECUREBITS_DEFAULT 0x00000000
++
++/* When set UID 0 has no special privileges. When unset, we support
++ inheritance of root-permissions and suid-root executable under
++ compatibility mode. We raise the effective and inheritable
bitmasks
++ *of the executable file* if the effective uid of the new process
is
++ 0. If the real uid is 0, we raise the effective (legacy) bit of
the
++ executable file. */
++#define SECURE_NOROOT 0
++#define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable
*/
++
++#define SECBIT_NOROOT (issecure_mask(SECURE_NOROOT))
++#define
SECBIT_NOROOT_LOCKED (issecure_mask(SECURE_NOROOT_LOCKED))
++
++/* When set, setuid to/from uid 0 does not trigger capability-
"fixup".
++ When unset, to provide compatiblility with old programs relying
on
++ set*uid to gain/lose privilege, transitions to/from uid 0 cause
++ capabilities to be gained/lost. */
++#define SECURE_NO_SETUID_FIXUP 2
++#define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable
*/
++
++#define
SECBIT_NO_SETUID_FIXUP (issecure_mask(SECURE_NO_SETUID_FIXUP))
++#define SECBIT_NO_SETUID_FIXUP_LOCKED \
++ (issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED
))
++
++/* When set, a process can retain its capabilities even after
++ transitioning to a non-root user (the set-uid fixup suppressed
by
++ bit 2). Bit-4 is cleared when a process calls exec(); setting
both
++ bit 4 and 5 will create a barrier through exec that no exec()'d
++ child can use this feature again. */
++#define SECURE_KEEP_CAPS 4
++#define SECURE_KEEP_CAPS_LOCKED 5 /* make bit-4
immutable */
++
++#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_L
OCKED))
++
++#define
SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \
++
issecure_mask(SECURE_NO_SETUID_FIXUP) | \
++ 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/lib/libcap/libcap.h b/lib/libcap/libcap.h
+index 5751651..dd0a9cd 100644
+--- a/lib/libcap/libcap.h
++++ b/lib/libcap/libcap.h
+@@ -1,7 +1,5 @@
+ /*
+- * Copyright (c) 1997 Andrew G Morgan <[email protected]>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997 Andrew G Morgan <[email protected]>
+ *
+ * This file contains internal definitions for the various
functions in
+ * this small capability library.
+@@ -14,19 +12,70 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <stdint.h>
+ #include "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 */
+ #include "cap_names.h"
+
++#ifndef _LINUX_CAPABILITY_U32S_1
++# define _LINUX_CAPABILITY_U32S_1 1
++#endif /* ndef _LINUX_CAPABILITY_U32S */
++
++/*
++ * Do we match the local kernel?
++ */
++
++#if !defined(_LINUX_CAPABILITY_VERSION)
++
++# error Kernel <linux/capability.h> does not support library
++# error file "libcap.h" --> fix and recompile libcap
++
++#elif !defined(_LINUX_CAPABILITY_VERSION_2)
++
++# warning Kernel <linux/capability.h> does not support 64-bit
capabilities
++# warning and libcap is being built with no support for 64-bit
capabilities
++
++# ifndef _LINUX_CAPABILITY_VERSION_1
++# define _LINUX_CAPABILITY_VERSION_1 0x19980330
++# endif
++
++# _LIBCAP_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1
++# _LIBCAP_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1
++
++#elif defined(_LINUX_CAPABILITY_VERSION_3)
++
++# if (_LINUX_CAPABILITY_VERSION_3 != 0x20080522)
++# error Kernel <linux/capability.h> v3 does not match library
++# error file "libcap.h" --> fix and recompile libcap
++# else
++# define _LIBCAP_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3
++# define _LIBCAP_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3
++# endif
++
++#elif (_LINUX_CAPABILITY_VERSION_2 != 0x20071026)
++
++# error Kernel <linux/capability.h> does not match library
++# error file "libcap.h" --> fix and recompile libcap
++
++#else
++
++# define _LIBCAP_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_2
++# define _LIBCAP_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_2
++
++#endif
++
++#undef _LINUX_CAPABILITY_VERSION
++#undef _LINUX_CAPABILITY_U32S
++
+ /*
+ * This is a pointer to a struct containing three consecutive
+ * capability sets in the order of the cap_flag_t type: the are
+@@ -36,53 +85,54 @@
+ * to processes.
+ */
+
+-#define CAP_T_MAGIC 0xCA90D0
+-struct _cap_struct {
+- struct __user_cap_header_struct head;
+- struct __user_cap_data_struct set;
++#if defined(VFS_CAP_REVISION_MASK) && !defined(VFS_CAP_U32)
++# define VFS_CAP_U32_1 1
++# define XATTR_CAPS_SZ_1 (sizeof(__le32)*(1 +
2*VFS_CAP_U32_1))
++# define VFS_CAP_U32 VFS_CAP_U32_1
++struct _cap_vfs_cap_data {
++ __le32 magic_etc;
++ struct {
++ __le32 permitted;
++ __le32 inheritable;
++ } data[VFS_CAP_U32_1];
+ };
++# define vfs_cap_data _cap_vfs_cap_data
++#endif
+
+-/* string magic for cap_free */
+-#define CAP_S_MAGIC 0xCA95D0
++#ifndef CAP_TO_INDEX
++# define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32
*/
++#endif /* ndef CAP_TO_INDEX */
+
+-/* Older Linux kernels only define _LINUX_CAPABILITY_VERSION.
Newer Linux
+- * kernels use _LINUX_CAPABILITY_VERSION_1 and
_LINUX_CAPABILITY_VERSION_2,
+- * and define _LINUX_CAPABILITY_VERSION to be
_LINUX_CAPABILITY_VERSION_2.
+- * This means that, for proper compilation and functioning on the
newer
+- * kernels, we need to use _LINUX_CAPABILITY_VERSION_1. But to
make sure
+- * we still compile on the older Linux kernels, we need to make
define
+- * our own _LINUX_CAPABILITY_VERSION_1 to be
_LINUX_CAPABILITY_VERSION.
+- */
+-#if !defined(_LINUX_CAPABILITY_VERSION_1) && \
+- defined(_LINUX_CAPABILITY_VERSION)
+-# define
_LINUX_CAPABILITY_VERSION_1 _LINUX_CAPABILITY_VERSION
+-#endif
++#ifndef CAP_TO_MASK
++# define CAP_TO_MASK(x) (1 << ((x) & 31))
++#endif /* ndef CAP_TO_MASK */
+
+-/*
+- * Do we match the local kernel?
+- */
++#define NUMBER_OF_CAP_SETS 3 /* effective, inheritable,
permitted */
++#define __CAP_BLKS (_LIBCAP_CAPABILITY_U32S)
++#define CAP_SET_SIZE (__CAP_BLKS * sizeof(__u32))
+
+-#if !defined(_LINUX_CAPABILITY_VERSION_1) || \
+- (_LINUX_CAPABILITY_VERSION_1 != 0x19980330)
++#define CAP_T_MAGIC 0xCA90D0
++struct _cap_struct {
++ struct __user_cap_header_struct head;
++ union {
++ struct __user_cap_data_struct set;
++ __u32 flat[NUMBER_OF_CAP_SETS];
++ } u[_LIBCAP_CAPABILITY_U32S];
++};
+
+-# error "Kernel <linux/capability.h> does not match library"
+-# error "file "libcap.h" --> fix and recompile libcap"
++/* the maximum bits supportable */
++#define __CAP_MAXBITS (__CAP_BLKS * 32)
+
+-#endif
++/* string magic for cap_free */
++#define CAP_S_MAGIC 0xCA95D0
+
+ /*
+ * kernel API cap set abstraction
+ */
+
+-#define NUMBER_OF_CAP_SETS 3 /* effective, inheritable,
permitted */
+-#define CAP_SET_SIZE (sizeof(struct
__user_cap_data_struct)/NUMBER_OF_CAP_SETS)
+-#define __CAP_BLKS (CAP_SET_SIZE/sizeof(__u32))
+-typedef struct {
+- __u32 _blk[__CAP_BLKS];
+-} __cap_s;
+-#define raise_cap(x) _blk[(x)>>5] |= (1<<((x)&31))
+-#define lower_cap(x) _blk[(x)>>5] &= ~(1<<((x)&31))
+-#define isset_cap(y,x) ((y)->_blk[(x)>>5] & (1<<((x)&31)))
++#define raise_cap(x,set) u[(x)>>5].flat[set] |=
(1<<((x)&31))
++#define lower_cap(x,set) u[(x)>>5].flat[set] &=
~(1<<((x)&31))
++#define isset_cap(y,x,set) ((y)->u[(x)>>5].flat[set] &
(1<<((x)&31)))
+
+ /*
+ * Private definitions for internal use by the library.
+@@ -92,25 +142,38 @@ typedef struct {
+ #define good_cap_t(c) __libcap_check_magic(c, CAP_T_MAGIC)
+ #define good_cap_string(c) __libcap_check_magic(c, CAP_S_MAGIC)
+
++/*
++ * These match CAP_DIFFERS() expectations
++ */
++#define LIBCAP_EFF (1 << CAP_EFFECTIVE)
++#define LIBCAP_INH (1 << CAP_INHERITABLE)
++#define LIBCAP_PER (1 << CAP_PERMITTED)
++
+ /*
+ * library debugging
+ */
+ #ifdef DEBUG
+
+ #include <stdio.h>
+-# define _cap_debug(f, x...) { \
+- fprintf(stderr, __FUNCTION__ "(" __FILE__ ":%d): ", __LINE__);
\
++# define _cap_debug(f, x...) do { \
++ fprintf(stderr, "%s(%s:%d): ", __FUNCTION__, __FILE__,
__LINE__); \
+ fprintf(stderr, f, ## x); \
+ fprintf(stderr, "\n"); \
+-}
+-# define _cap_debugcap(s, c) \
+- fprintf(stderr, __FUNCTION__ "(" __FILE__ ":%d): " s \
+- "%08x\n", __LINE__, *(c))
++} while (0)
++
++# define _cap_debugcap(s, c, set) do { \
++ unsigned _cap_index; \
++ fprintf(stderr, "%s(%s:%d): %s", __FUNCTION__, __FILE__,
__LINE__, s); \
++ for (_cap_index=_LIBCAP_CAPABILITY_U32S; _cap_index-- > 0; ) {
\
++ fprintf(stderr, "%08x", (c).u[_cap_index].flat[set]); \
++ } \
++ fprintf(stderr, "\n"); \
++} while (0)
+
+ #else /* !DEBUG */
+
+ # define _cap_debug(f, x...)
+-# define _cap_debugcap(s, c)
++# define _cap_debugcap(s, c, set)
+
+ #endif /* DEBUG */
+
+@@ -127,58 +190,20 @@ extern int capget(cap_user_header_t header,
const cap_user_data_t data);
+ extern int capgetp(pid_t pid, cap_t cap_d);
+ extern int capsetp(pid_t pid, cap_t cap_d);
+
+-#endif /* LIBCAP_H */
++/* prctl based API for altering character of current process */
++#define PR_GET_KEEPCAPS 7
++#define PR_SET_KEEPCAPS 8
++#define PR_CAPBSET_READ 23
++#define PR_CAPBSET_DROP 24
++#define PR_GET_SECUREBITS 27
++#define PR_SET_SECUREBITS 28
+
+ /*
+- * $Log: libcap.h,v $
+- * Revision 1.5 2008-08-23 02:49:48 castaglia
+- *
+- * Fix typo (missing backslash).
+- *
+- * Revision 1.4 2008/08/22 16:35:52 castaglia
+- *
+- * Try to handle the change in Linux capability version macro names
for
+- * older kernels (which don't define/use the new names).
+- *
+- * Revision 1.3 2008/08/06 17:00:41 castaglia
+- *
+- * Bug#3096 - libcap version errors on newer Linux kernel. Newer
Linux kernels
+- * have a _LINUX_CAPABILITY_VERSION_2 macro, and redefine the old
+- * _LINUX_CAPABILITY_VERSION macro. To play better with such
kernels, redefine
+- * the bundled libcap to use _LINUX_CAPABILITY_VERSION_1.
+- *
+- * Revision 1.2 2003/05/15 00:49:13 castaglia
+- *
+- * Bug#2000 - mod_cap should not use bundled libcap. This patch
updates the
+- * bundled libcap; I won't be closing the bug report just yet.
+- *
+- * Revision 1.1 2003/01/03 02:16:17 jwm
+- *
+- * Turning mod_linuxprivs into a core module, mod_cap. This is by
no means
+- * complete.
+- *
+- * Revision 1.2 1999/09/07 23:14:19 macgyver
+- * Updated capabilities library and model.
+- *
+- * Revision 1.2 1999/04/17 23:25:10 morgan
+- * fixes from peeterj
+- *
+- * Revision 1.1.1.1 1999/04/17 22:16:31 morgan
+- * release 1.0 of libcap
+- *
+- * Revision 1.5 1998/06/08 00:15:28 morgan
+- * accommodate alpha (glibc?)
+- *
+- * Revision 1.4 1998/06/07 15:58:23 morgan
+- * accommodate real kernel header files :*)
+- *
+- * Revision 1.3 1998/05/24 22:54:09 morgan
+- * updated for 2.1.104
+- *
+- * Revision 1.2 1997/04/28 00:57:11 morgan
+- * zefram's replacement file with a number of bug fixes from AGM
+- *
+- * Revision 1.1 1997/04/21 04:32:52 morgan
+- * Initial revision
+- *
++ * 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 */
+--
+2.25.1
+
diff --git a/meta-networking/recipes-daemons/proftpd/proftpd_1.3.6.bb
b/meta-networking/recipes-daemons/proftpd/proftpd_1.3.6.bb
index aa1f9e4ef9..08ec3b63ee 100644
--- a/meta-networking/recipes-daemons/proftpd/proftpd_1.3.6.bb
+++ b/meta-networking/recipes-daemons/proftpd/proftpd_1.3.6.bb
@@ -14,6 +14,7 @@ SRC_URI =
"ftp://ftp.proftpd.org/distrib/source/${BPN}-${PV}.tar.gz \
file://proftpd.service \
file://CVE-2021-46854.patch \
file://CVE-2023-51713.patch \
+ file://CVE-2020-9272.patch \
"
SRC_URI[md5sum] = "13270911c42aac842435f18205546a1b"
SRC_URI[sha256sum] =
"91ef74b143495d5ff97c4d4770c6804072a8c8eb1ad1ecc8cc541b40e152ecaf"