Upstream-Status: Backport from 
https://github.com/proftpd/proftpd/commit/743330874ee19dfcf2405827274015da0663bd2b

Signed-off-by: Hitendra Prajapati <[email protected]>
---
 .../proftpd/files/CVE-2020-9272.patch         | 2839 +++++++++++++++++
 .../recipes-daemons/proftpd/proftpd_1.3.6.bb  |    1 +
 2 files changed, 2840 insertions(+)
 create mode 100644 
meta-networking/recipes-daemons/proftpd/files/CVE-2020-9272.patch

diff --git a/meta-networking/recipes-daemons/proftpd/files/CVE-2020-9272.patch 
b/meta-networking/recipes-daemons/proftpd/files/CVE-2020-9272.patch
new file mode 100644
index 0000000000..aa779a0956
--- /dev/null
+++ b/meta-networking/recipes-daemons/proftpd/files/CVE-2020-9272.patch
@@ -0,0 +1,2839 @@
+From 743330874ee19dfcf2405827274015da0663bd2b Mon Sep 17 00:00:00 2001
+From: TJ Saunders <[email protected]>
+Date: Tue, 18 Feb 2020 11:21:38 -0800
+Subject: [PATCH] Issue #902: Update the bundled `libcap` library to the latest
+ from https://github.com/mhiramat/libcap.git.
+
+Upstream-Status: Backport 
[https://github.com/proftpd/proftpd/commit/743330874ee19dfcf2405827274015da0663bd2b]
+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_LOCKED))
++
++#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"
-- 
2.25.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#109028): 
https://lists.openembedded.org/g/openembedded-devel/message/109028
Mute This Topic: https://lists.openembedded.org/mt/104577724/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to