diff mbox series

[meta-networking,dunfell] proftpd: fix CVE-2020-9272 Out-of-bounds read

Message ID 20240226055525.30105-1-hprajapati@mvista.com
State New
Headers show
Series [meta-networking,dunfell] proftpd: fix CVE-2020-9272 Out-of-bounds read | expand

Commit Message

Hitendra Prajapati Feb. 26, 2024, 5:55 a.m. UTC
Upstream-Status: Backport from https://github.com/proftpd/proftpd/commit/743330874ee19dfcf2405827274015da0663bd2b

Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
---
 .../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

Comments

Mittal, Anuj Feb. 26, 2024, 8:55 a.m. UTC | #1
On Mon, 2024-02-26 at 11:25 +0530, Hitendra Prajapati via
lists.openembedded.org wrote:
> Upstream-Status: Backport from
> https://github.com/proftpd/proftpd/commit/743330874ee19dfcf2405827274015da0663bd2b
> 
> Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
> ---
>  .../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 <tj@castaglia.org>
> +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/743330874ee19dfcf240582727
> 4015da0663bd2b]

I think it'd be better to update the recipe to 1.3.6e maintenance
release that already has this fix instead of carrying this patch.

http://proftpd.org/docs/RELEASE_NOTES-1.3.6e

Thanks,

Anuj

> +CVE: CVE-2020-9272
> +Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
> +---
> + 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 core@proftpd.org.
> +@@ -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 <morgan@linux.kernel.org>
> ++ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@kernel.org>
> +  *
> +  * 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 <morgan@linux.kernel.org>
> +- *
> +- * See end of file for Log.
> ++ * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
> +  *
> +  * 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 <morgan@linux.kernel.org>
> +- *
> +- * See end of file for Log.
> ++ * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
> +  *
> +  * 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 <morgan@linux.kernel.org>
> +- *
> +- * See end of file for Log.
> ++ * Copyright (c) 1997,2007,2016 Andrew G Morgan <morgan@kernel.org>
> +  *
> +  * 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 <morgan@linux.kernel.org>
> +- *
> +- * See end of file for Log.
> ++ * Copyright (c) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
> +  *
> +  * 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 <morgan@linux.kernel.org>
> ++ * Copyright (c) 1997-8,2007,2011 Andrew G Morgan
> <morgan@kernel.org>
> +  *
> +- * 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  
> <morgan@linux.kernel.org>
> +- *
> +- * 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 <morgan@linux.kernel.org>
> ++ * Copyright (c) 1997-8,2007-8 Andrew G Morgan <morgan@kernel.org>
> +  * Copyright (c) 1997 Andrew Main <zefram@dcs.warwick.ac.uk>
> +  *
> +- * 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 <morgan@linux.kernel.org>
> ++ * Copyright (C) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
> +  *
> +  * 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 <serue@us.ibm.com>
> ++ */
> ++
> ++#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 <morgan@kernel.org>
> ++ * Alexander Kjeldaas <astor@guardian.no>
> ++ * with help from Aleph1, Roland Buresund and Andrew Main.
> ++ *
> ++ * See here for the libcap library ("POSIX draft" compliance):
> ++ *
> ++ * http://www.kernel.org/pub/linux/libs/security/linux-privs/
> ++ */
> ++
> ++#ifndef _UAPI_LINUX_CAPABILITY_H
> ++#define _UAPI_LINUX_CAPABILITY_H
> ++
> ++#include <linux/types.h>
> ++
> ++struct task_struct;
> ++
> ++/* User-level do most of the mapping between kernel and user
> ++   capabilities based on the version tag given by the kernel. The
> ++   kernel might be somewhat backwards compatible, but don't bet on
> ++   it. */
> ++
> ++/* Note, cap_t, is defined by POSIX (draft) to be an "opaque"
> pointer to
> ++   a set of three capability sets.  The transposition of 3*the
> ++   following structure to such a composite is better handled in a
> user
> ++   library since the draft standard requires the use of malloc/free
> ++   etc.. */
> ++
> ++#define _LINUX_CAPABILITY_VERSION_1  0x19980330
> ++#define _LINUX_CAPABILITY_U32S_1     1
> ++
> ++#define _LINUX_CAPABILITY_VERSION_2  0x20071026  /* deprecated -
> use v3 */
> ++#define _LINUX_CAPABILITY_U32S_2     2
> ++
> ++#define _LINUX_CAPABILITY_VERSION_3  0x20080522
> ++#define _LINUX_CAPABILITY_U32S_3     2
> ++
> ++typedef struct __user_cap_header_struct {
> ++	__u32 version;
> ++	int pid;
> ++} __user *cap_user_header_t;
> ++
> ++typedef struct __user_cap_data_struct {
> ++        __u32 effective;
> ++        __u32 permitted;
> ++        __u32 inheritable;
> ++} __user *cap_user_data_t;
> ++
> ++
> ++#define VFS_CAP_REVISION_MASK	0xFF000000
> ++#define VFS_CAP_REVISION_SHIFT	24
> ++#define VFS_CAP_FLAGS_MASK	~VFS_CAP_REVISION_MASK
> ++#define VFS_CAP_FLAGS_EFFECTIVE	0x000001
> ++
> ++#define VFS_CAP_REVISION_1	0x01000000
> ++#define VFS_CAP_U32_1           1
> ++#define XATTR_CAPS_SZ_1         (sizeof(__le32)*(1 +
> 2*VFS_CAP_U32_1))
> ++
> ++#define VFS_CAP_REVISION_2	0x02000000
> ++#define VFS_CAP_U32_2           2
> ++#define XATTR_CAPS_SZ_2         (sizeof(__le32)*(1 +
> 2*VFS_CAP_U32_2))
> ++
> ++#define XATTR_CAPS_SZ           XATTR_CAPS_SZ_2
> ++#define VFS_CAP_U32             VFS_CAP_U32_2
> ++#define VFS_CAP_REVISION	VFS_CAP_REVISION_2
> ++
> ++struct vfs_cap_data {
> ++	__le32 magic_etc;            /* Little endian */
> ++	struct {
> ++		__le32 permitted;    /* Little endian */
> ++		__le32 inheritable;  /* Little endian */
> ++	} data[VFS_CAP_U32];
> ++};
> ++
> ++#ifndef __KERNEL__
> ++
> ++/*
> ++ * Backwardly compatible definition for source code - trapped in a
> ++ * 32-bit world. If you find you need this, please consider using
> ++ * libcap to untrap yourself...
> ++ */
> ++#define _LINUX_CAPABILITY_VERSION  _LINUX_CAPABILITY_VERSION_1
> ++#define _LINUX_CAPABILITY_U32S     _LINUX_CAPABILITY_U32S_1
> ++
> ++#endif
> ++
> ++
> ++/**
> ++ ** POSIX-draft defined capabilities.
> ++ **/
> ++
> ++/* In a system with the [_POSIX_CHOWN_RESTRICTED] option defined,
> this
> ++   overrides the restriction of changing file ownership and group
> ++   ownership. */
> ++
> ++#define CAP_CHOWN            0
> ++
> ++/* Override all DAC access, including ACL execute access if
> ++   [_POSIX_ACL] is defined. Excluding DAC access covered by
> ++   CAP_LINUX_IMMUTABLE. */
> ++
> ++#define CAP_DAC_OVERRIDE     1
> ++
> ++/* Overrides all DAC restrictions regarding read and search on
> files
> ++   and directories, including ACL restrictions if [_POSIX_ACL] is
> ++   defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */
> ++
> ++#define CAP_DAC_READ_SEARCH  2
> ++
> ++/* Overrides all restrictions about allowed operations on files,
> where
> ++   file owner ID must be equal to the user ID, except where
> CAP_FSETID
> ++   is applicable. It doesn't override MAC and DAC restrictions. */
> ++
> ++#define CAP_FOWNER           3
> ++
> ++/* Overrides the following restrictions that the effective user ID
> ++   shall match the file owner ID when setting the S_ISUID and
> S_ISGID
> ++   bits on that file; that the effective group ID (or one of the
> ++   supplementary group IDs) shall match the file owner ID when
> setting
> ++   the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits
> are
> ++   cleared on successful return from chown(2) (not implemented). */
> ++
> ++#define CAP_FSETID           4
> ++
> ++/* Overrides the restriction that the real or effective user ID of
> a
> ++   process sending a signal must match the real or effective user
> ID
> ++   of the process receiving the signal. */
> ++
> ++#define CAP_KILL             5
> ++
> ++/* Allows setgid(2) manipulation */
> ++/* Allows setgroups(2) */
> ++/* Allows forged gids on socket credentials passing. */
> ++
> ++#define CAP_SETGID           6
> ++
> ++/* Allows set*uid(2) manipulation (including fsuid). */
> ++/* Allows forged pids on socket credentials passing. */
> ++
> ++#define CAP_SETUID           7
> ++
> ++
> ++/**
> ++ ** Linux-specific capabilities
> ++ **/
> ++
> ++/* Without VFS support for capabilities:
> ++ *   Transfer any capability in your permitted set to any pid,
> ++ *   remove any capability in your permitted set from any pid
> ++ * With VFS support for capabilities (neither of above, but)
> ++ *   Add any capability from current's capability bounding set
> ++ *       to the current process' inheritable set
> ++ *   Allow taking bits out of capability bounding set
> ++ *   Allow modification of the securebits for a process
> ++ */
> ++
> ++#define CAP_SETPCAP          8
> ++
> ++/* Allow modification of S_IMMUTABLE and S_APPEND file attributes
> */
> ++
> ++#define CAP_LINUX_IMMUTABLE  9
> ++
> ++/* Allows binding to TCP/UDP sockets below 1024 */
> ++/* Allows binding to ATM VCIs below 32 */
> ++
> ++#define CAP_NET_BIND_SERVICE 10
> ++
> ++/* Allow broadcasting, listen to multicast */
> ++
> ++#define CAP_NET_BROADCAST    11
> ++
> ++/* Allow interface configuration */
> ++/* Allow administration of IP firewall, masquerading and accounting
> */
> ++/* Allow setting debug option on sockets */
> ++/* Allow modification of routing tables */
> ++/* Allow setting arbitrary process / process group ownership on
> ++   sockets */
> ++/* Allow binding to any address for transparent proxying (also via
> NET_RAW) */
> ++/* Allow setting TOS (type of service) */
> ++/* Allow setting promiscuous mode */
> ++/* Allow clearing driver statistics */
> ++/* Allow multicasting */
> ++/* Allow read/write of device-specific registers */
> ++/* Allow activation of ATM control sockets */
> ++
> ++#define CAP_NET_ADMIN        12
> ++
> ++/* Allow use of RAW sockets */
> ++/* Allow use of PACKET sockets */
> ++/* Allow binding to any address for transparent proxying (also via
> NET_ADMIN) */
> ++
> ++#define CAP_NET_RAW          13
> ++
> ++/* Allow locking of shared memory segments */
> ++/* Allow mlock and mlockall (which doesn't really have anything to
> do
> ++   with IPC) */
> ++
> ++#define CAP_IPC_LOCK         14
> ++
> ++/* Override IPC ownership checks */
> ++
> ++#define CAP_IPC_OWNER        15
> ++
> ++/* Insert and remove kernel modules - modify kernel without limit
> */
> ++#define CAP_SYS_MODULE       16
> ++
> ++/* Allow ioperm/iopl access */
> ++/* Allow sending USB messages to any device via /proc/bus/usb */
> ++
> ++#define CAP_SYS_RAWIO        17
> ++
> ++/* Allow use of chroot() */
> ++
> ++#define CAP_SYS_CHROOT       18
> ++
> ++/* Allow ptrace() of any process */
> ++
> ++#define CAP_SYS_PTRACE       19
> ++
> ++/* Allow configuration of process accounting */
> ++
> ++#define CAP_SYS_PACCT        20
> ++
> ++/* Allow configuration of the secure attention key */
> ++/* Allow administration of the random device */
> ++/* Allow examination and configuration of disk quotas */
> ++/* Allow setting the domainname */
> ++/* Allow setting the hostname */
> ++/* Allow calling bdflush() */
> ++/* Allow mount() and umount(), setting up new smb connection */
> ++/* Allow some autofs root ioctls */
> ++/* Allow nfsservctl */
> ++/* Allow VM86_REQUEST_IRQ */
> ++/* Allow to read/write pci config on alpha */
> ++/* Allow irix_prctl on mips (setstacksize) */
> ++/* Allow flushing all cache on m68k (sys_cacheflush) */
> ++/* Allow removing semaphores */
> ++/* Used instead of CAP_CHOWN to "chown" IPC message queues,
> semaphores
> ++   and shared memory */
> ++/* Allow locking/unlocking of shared memory segment */
> ++/* Allow turning swap on/off */
> ++/* Allow forged pids on socket credentials passing */
> ++/* Allow setting readahead and flushing buffers on block devices */
> ++/* Allow setting geometry in floppy driver */
> ++/* Allow turning DMA on/off in xd driver */
> ++/* Allow administration of md devices (mostly the above, but some
> ++   extra ioctls) */
> ++/* Allow tuning the ide driver */
> ++/* Allow access to the nvram device */
> ++/* Allow administration of apm_bios, serial and bttv (TV) device */
> ++/* Allow manufacturer commands in isdn CAPI support driver */
> ++/* Allow reading non-standardized portions of pci configuration
> space */
> ++/* Allow DDI debug ioctl on sbpcd driver */
> ++/* Allow setting up serial ports */
> ++/* Allow sending raw qic-117 commands */
> ++/* Allow enabling/disabling tagged queuing on SCSI controllers and
> sending
> ++   arbitrary SCSI commands */
> ++/* Allow setting encryption key on loopback filesystem */
> ++/* Allow setting zone reclaim policy */
> ++
> ++#define CAP_SYS_ADMIN        21
> ++
> ++/* Allow use of reboot() */
> ++
> ++#define CAP_SYS_BOOT         22
> ++
> ++/* Allow raising priority and setting priority on other (different
> ++   UID) processes */
> ++/* Allow use of FIFO and round-robin (realtime) scheduling on own
> ++   processes and setting the scheduling algorithm used by another
> ++   process. */
> ++/* Allow setting cpu affinity on other processes */
> ++
> ++#define CAP_SYS_NICE         23
> ++
> ++/* Override resource limits. Set resource limits. */
> ++/* Override quota limits. */
> ++/* Override reserved space on ext2 filesystem */
> ++/* Modify data journaling mode on ext3 filesystem (uses journaling
> ++   resources) */
> ++/* NOTE: ext2 honors fsuid when checking for resource overrides, so
> ++   you can override using fsuid too */
> ++/* Override size restrictions on IPC message queues */
> ++/* Allow more than 64hz interrupts from the real-time clock */
> ++/* Override max number of consoles on console allocation */
> ++/* Override max number of keymaps */
> ++
> ++#define CAP_SYS_RESOURCE     24
> ++
> ++/* Allow manipulation of system clock */
> ++/* Allow irix_stime on mips */
> ++/* Allow setting the real-time clock */
> ++
> ++#define CAP_SYS_TIME         25
> ++
> ++/* Allow configuration of tty devices */
> ++/* Allow vhangup() of tty */
> ++
> ++#define CAP_SYS_TTY_CONFIG   26
> ++
> ++/* Allow the privileged aspects of mknod() */
> ++
> ++#define CAP_MKNOD            27
> ++
> ++/* Allow taking of leases on files */
> ++
> ++#define CAP_LEASE            28
> ++
> ++/* Allow writing the audit log via unicast netlink socket */
> ++
> ++#define CAP_AUDIT_WRITE      29
> ++
> ++/* Allow configuration of audit via unicast netlink socket */
> ++
> ++#define CAP_AUDIT_CONTROL    30
> ++
> ++#define CAP_SETFCAP	     31
> ++
> ++/* Override MAC access.
> ++   The base kernel enforces no MAC policy.
> ++   An LSM may enforce a MAC policy, and if it does and it chooses
> ++   to implement capability based overrides of that policy, this is
> ++   the capability it should use to do so. */
> ++
> ++#define CAP_MAC_OVERRIDE     32
> ++
> ++/* Allow MAC configuration or state changes.
> ++   The base kernel requires no MAC configuration.
> ++   An LSM may enforce a MAC policy, and if it does and it chooses
> ++   to implement capability based checks on modifications to that
> ++   policy or the data required to maintain it, this is the
> ++   capability it should use to do so. */
> ++
> ++#define CAP_MAC_ADMIN        33
> ++
> ++/* Allow configuring the kernel's syslog (printk behaviour) */
> ++
> ++#define CAP_SYSLOG           34
> ++
> ++/* Allow triggering something that will wake the system */
> ++
> ++#define CAP_WAKE_ALARM            35
> ++
> ++/* Allow preventing system suspends */
> ++
> ++#define CAP_BLOCK_SUSPEND    36
> ++
> ++/* Allow reading the audit log via multicast netlink socket */
> ++
> ++#define CAP_AUDIT_READ       37
> ++
> ++
> ++#define CAP_LAST_CAP         CAP_AUDIT_READ
> ++
> ++#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
> ++
> ++/*
> ++ * Bit location of each capability (used by user-space library and
> kernel)
> ++ */
> ++
> ++#define CAP_TO_INDEX(x)     ((x) >> 5)        /* 1 << 5 == bits in
> __u32 */
> ++#define CAP_TO_MASK(x)      (1 << ((x) & 31)) /* mask for indexed
> __u32 */
> ++
> ++
> ++#endif /* _UAPI_LINUX_CAPABILITY_H */
> +diff --git a/lib/libcap/include/uapi/linux/prctl.h
> b/lib/libcap/include/uapi/linux/prctl.h
> +new file mode 100644
> +index 0000000..a8d0759
> +--- /dev/null
> ++++ b/lib/libcap/include/uapi/linux/prctl.h
> +@@ -0,0 +1,200 @@
> ++#ifndef _LINUX_PRCTL_H
> ++#define _LINUX_PRCTL_H
> ++
> ++#include <linux/types.h>
> ++
> ++/* Values to pass as first argument to prctl() */
> ++
> ++#define PR_SET_PDEATHSIG  1  /* Second arg is a signal */
> ++#define PR_GET_PDEATHSIG  2  /* Second arg is a ptr to return the
> signal */
> ++
> ++/* Get/set current->mm->dumpable */
> ++#define PR_GET_DUMPABLE   3
> ++#define PR_SET_DUMPABLE   4
> ++
> ++/* Get/set unaligned access control bits (if meaningful) */
> ++#define PR_GET_UNALIGN	  5
> ++#define PR_SET_UNALIGN	  6
> ++# define PR_UNALIGN_NOPRINT	1	/* silently fix up unaligned
> user accesses */
> ++# define PR_UNALIGN_SIGBUS	2	/* generate SIGBUS on
> unaligned user access */
> ++
> ++/* Get/set whether or not to drop capabilities on setuid() away
> from
> ++ * uid 0 (as per security/commoncap.c) */
> ++#define PR_GET_KEEPCAPS   7
> ++#define PR_SET_KEEPCAPS   8
> ++
> ++/* Get/set floating-point emulation control bits (if meaningful) */
> ++#define PR_GET_FPEMU  9
> ++#define PR_SET_FPEMU 10
> ++# define PR_FPEMU_NOPRINT	1	/* silently emulate fp
> operations accesses */
> ++# define PR_FPEMU_SIGFPE	2	/* don't emulate fp
> operations, send SIGFPE instead */
> ++
> ++/* Get/set floating-point exception mode (if meaningful) */
> ++#define PR_GET_FPEXC	11
> ++#define PR_SET_FPEXC	12
> ++# define PR_FP_EXC_SW_ENABLE	0x80	/* Use FPEXC for FP
> exception enables */
> ++# define PR_FP_EXC_DIV		0x010000	/* floating
> point divide by zero */
> ++# define PR_FP_EXC_OVF		0x020000	/* floating
> point overflow */
> ++# define PR_FP_EXC_UND		0x040000	/* floating
> point underflow */
> ++# define PR_FP_EXC_RES		0x080000	/* floating
> point inexact result */
> ++# define PR_FP_EXC_INV		0x100000	/* floating
> point invalid operation */
> ++# define PR_FP_EXC_DISABLED	0	/* FP exceptions disabled */
> ++# define PR_FP_EXC_NONRECOV	1	/* async non-recoverable
> exc. mode */
> ++# define PR_FP_EXC_ASYNC	2	/* async recoverable
> exception mode */
> ++# define PR_FP_EXC_PRECISE	3	/* precise exception mode */
> ++
> ++/* Get/set whether we use statistical process timing or accurate
> timestamp
> ++ * based process timing */
> ++#define PR_GET_TIMING   13
> ++#define PR_SET_TIMING   14
> ++# define PR_TIMING_STATISTICAL  0       /* Normal, traditional,
> ++                                                   statistical
> process timing */
> ++# define PR_TIMING_TIMESTAMP    1       /* Accurate timestamp based
> ++                                                   process timing
> */
> ++
> ++#define PR_SET_NAME    15		/* Set process name */
> ++#define PR_GET_NAME    16		/* Get process name */
> ++
> ++/* Get/set process endian */
> ++#define PR_GET_ENDIAN	19
> ++#define PR_SET_ENDIAN	20
> ++# define PR_ENDIAN_BIG		0
> ++# define PR_ENDIAN_LITTLE	1	/* True little endian mode
> */
> ++# define PR_ENDIAN_PPC_LITTLE	2	/* "PowerPC" pseudo little
> endian */
> ++
> ++/* Get/set process seccomp mode */
> ++#define PR_GET_SECCOMP	21
> ++#define PR_SET_SECCOMP	22
> ++
> ++/* Get/set the capability bounding set (as per
> security/commoncap.c) */
> ++#define PR_CAPBSET_READ 23
> ++#define PR_CAPBSET_DROP 24
> ++
> ++/* Get/set the process' ability to use the timestamp counter
> instruction */
> ++#define PR_GET_TSC 25
> ++#define PR_SET_TSC 26
> ++# define PR_TSC_ENABLE		1	/* allow the use of
> the timestamp counter */
> ++# define PR_TSC_SIGSEGV		2	/* throw a SIGSEGV
> instead of reading the TSC */
> ++
> ++/* Get/set securebits (as per security/commoncap.c) */
> ++#define PR_GET_SECUREBITS 27
> ++#define PR_SET_SECUREBITS 28
> ++
> ++/*
> ++ * Get/set the timerslack as used by poll/select/nanosleep
> ++ * A value of 0 means "use default"
> ++ */
> ++#define PR_SET_TIMERSLACK 29
> ++#define PR_GET_TIMERSLACK 30
> ++
> ++#define PR_TASK_PERF_EVENTS_DISABLE		31
> ++#define PR_TASK_PERF_EVENTS_ENABLE		32
> ++
> ++/*
> ++ * Set early/late kill mode for hwpoison memory corruption.
> ++ * This influences when the process gets killed on a memory
> corruption.
> ++ */
> ++#define PR_MCE_KILL	33
> ++# define PR_MCE_KILL_CLEAR   0
> ++# define PR_MCE_KILL_SET     1
> ++
> ++# define PR_MCE_KILL_LATE    0
> ++# define PR_MCE_KILL_EARLY   1
> ++# define PR_MCE_KILL_DEFAULT 2
> ++
> ++#define PR_MCE_KILL_GET 34
> ++
> ++/*
> ++ * Tune up process memory map specifics.
> ++ */
> ++#define PR_SET_MM		35
> ++# define PR_SET_MM_START_CODE		1
> ++# define PR_SET_MM_END_CODE		2
> ++# define PR_SET_MM_START_DATA		3
> ++# define PR_SET_MM_END_DATA		4
> ++# define PR_SET_MM_START_STACK		5
> ++# define PR_SET_MM_START_BRK		6
> ++# define PR_SET_MM_BRK			7
> ++# define PR_SET_MM_ARG_START		8
> ++# define PR_SET_MM_ARG_END		9
> ++# define PR_SET_MM_ENV_START		10
> ++# define PR_SET_MM_ENV_END		11
> ++# define PR_SET_MM_AUXV			12
> ++# define PR_SET_MM_EXE_FILE		13
> ++# define PR_SET_MM_MAP			14
> ++# define PR_SET_MM_MAP_SIZE		15
> ++
> ++/*
> ++ * This structure provides new memory descriptor
> ++ * map which mostly modifies /proc/pid/stat[m]
> ++ * output for a task. This mostly done in a
> ++ * sake of checkpoint/restore functionality.
> ++ */
> ++struct prctl_mm_map {
> ++	__u64	start_code;		/* code section bounds */
> ++	__u64	end_code;
> ++	__u64	start_data;		/* data section bounds */
> ++	__u64	end_data;
> ++	__u64	start_brk;		/* heap for brk() syscall */
> ++	__u64	brk;
> ++	__u64	start_stack;		/* stack starts at */
> ++	__u64	arg_start;		/* command line arguments
> bounds */
> ++	__u64	arg_end;
> ++	__u64	env_start;		/* environment variables
> bounds */
> ++	__u64	env_end;
> ++	__u64	*auxv;			/* auxiliary vector */
> ++	__u32	auxv_size;		/* vector size */
> ++	__u32	exe_fd;			/* /proc/$pid/exe
> link file */
> ++};
> ++
> ++/*
> ++ * Set specific pid that is allowed to ptrace the current task.
> ++ * A value of 0 mean "no process".
> ++ */
> ++#define PR_SET_PTRACER 0x59616d61
> ++# define PR_SET_PTRACER_ANY ((unsigned long)-1)
> ++
> ++#define PR_SET_CHILD_SUBREAPER	36
> ++#define PR_GET_CHILD_SUBREAPER	37
> ++
> ++/*
> ++ * If no_new_privs is set, then operations that grant new
> privileges (i.e.
> ++ * execve) will either fail or not grant them.  This affects
> suid/sgid,
> ++ * file capabilities, and LSMs.
> ++ *
> ++ * Operations that merely manipulate or drop existing privileges
> (setresuid,
> ++ * capset, etc.) will still work.  Drop those privileges if you
> want them gone.
> ++ *
> ++ * Changing LSM security domain is considered a new privilege.  So,
> for example,
> ++ * asking selinux for a specific new context (e.g. with runcon)
> will result
> ++ * in execve returning -EPERM.
> ++ *
> ++ * See Documentation/prctl/no_new_privs.txt for more details.
> ++ */
> ++#define PR_SET_NO_NEW_PRIVS	38
> ++#define PR_GET_NO_NEW_PRIVS	39
> ++
> ++#define PR_GET_TID_ADDRESS	40
> ++
> ++#define PR_SET_THP_DISABLE	41
> ++#define PR_GET_THP_DISABLE	42
> ++
> ++/*
> ++ * Tell the kernel to start/stop helping userspace manage bounds
> tables.
> ++ */
> ++#define PR_MPX_ENABLE_MANAGEMENT  43
> ++#define PR_MPX_DISABLE_MANAGEMENT 44
> ++
> ++#define PR_SET_FP_MODE		45
> ++#define PR_GET_FP_MODE		46
> ++# define PR_FP_MODE_FR		(1 << 0)	/* 64b FP
> registers */
> ++# define PR_FP_MODE_FRE		(1 << 1)	/* 32b
> compatibility */
> ++
> ++/* Control the ambient capability set */
> ++#define PR_CAP_AMBIENT			47
> ++# define PR_CAP_AMBIENT_IS_SET		1
> ++# define PR_CAP_AMBIENT_RAISE		2
> ++# define PR_CAP_AMBIENT_LOWER		3
> ++# define PR_CAP_AMBIENT_CLEAR_ALL	4
> ++
> ++#endif /* _LINUX_PRCTL_H */
> +diff --git a/lib/libcap/include/uapi/linux/securebits.h
> b/lib/libcap/include/uapi/linux/securebits.h
> +new file mode 100644
> +index 0000000..35ac35c
> +--- /dev/null
> ++++ b/lib/libcap/include/uapi/linux/securebits.h
> +@@ -0,0 +1,60 @@
> ++#ifndef _UAPI_LINUX_SECUREBITS_H
> ++#define _UAPI_LINUX_SECUREBITS_H
> ++
> ++/* Each securesetting is implemented using two bits. One bit
> specifies
> ++   whether the setting is on or off. The other bit specify whether
> the
> ++   setting is locked or not. A setting which is locked cannot be
> ++   changed from user-level. */
> ++#define issecure_mask(X)	(1 << (X))
> ++
> ++#define SECUREBITS_DEFAULT 0x00000000
> ++
> ++/* When set UID 0 has no special privileges. When unset, we support
> ++   inheritance of root-permissions and suid-root executable under
> ++   compatibility mode. We raise the effective and inheritable
> bitmasks
> ++   *of the executable file* if the effective uid of the new process
> is
> ++   0. If the real uid is 0, we raise the effective (legacy) bit of
> the
> ++   executable file. */
> ++#define SECURE_NOROOT			0
> ++#define SECURE_NOROOT_LOCKED		1  /* make bit-0 immutable
> */
> ++
> ++#define SECBIT_NOROOT		(issecure_mask(SECURE_NOROOT))
> ++#define
> SECBIT_NOROOT_LOCKED	(issecure_mask(SECURE_NOROOT_LOCKED))
> ++
> ++/* When set, setuid to/from uid 0 does not trigger capability-
> "fixup".
> ++   When unset, to provide compatiblility with old programs relying
> on
> ++   set*uid to gain/lose privilege, transitions to/from uid 0 cause
> ++   capabilities to be gained/lost. */
> ++#define SECURE_NO_SETUID_FIXUP		2
> ++#define SECURE_NO_SETUID_FIXUP_LOCKED	3  /* make bit-2 immutable
> */
> ++
> ++#define
> SECBIT_NO_SETUID_FIXUP	(issecure_mask(SECURE_NO_SETUID_FIXUP))
> ++#define SECBIT_NO_SETUID_FIXUP_LOCKED \
> ++			(issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED
> ))
> ++
> ++/* When set, a process can retain its capabilities even after
> ++   transitioning to a non-root user (the set-uid fixup suppressed
> by
> ++   bit 2). Bit-4 is cleared when a process calls exec(); setting
> both
> ++   bit 4 and 5 will create a barrier through exec that no exec()'d
> ++   child can use this feature again. */
> ++#define SECURE_KEEP_CAPS		4
> ++#define SECURE_KEEP_CAPS_LOCKED		5  /* make bit-4
> immutable */
> ++
> ++#define SECBIT_KEEP_CAPS	(issecure_mask(SECURE_KEEP_CAPS))
> ++#define SECBIT_KEEP_CAPS_LOCKED
> (issecure_mask(SECURE_KEEP_CAPS_LOCKED))
> ++
> ++/* When set, a process cannot add new capabilities to its ambient
> set. */
> ++#define SECURE_NO_CAP_AMBIENT_RAISE		6
> ++#define SECURE_NO_CAP_AMBIENT_RAISE_LOCKED	7  /* make bit-6
> immutable */
> ++
> ++#define SECBIT_NO_CAP_AMBIENT_RAISE
> (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))
> ++#define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED \
> ++			(issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_L
> OCKED))
> ++
> ++#define
> SECURE_ALL_BITS		(issecure_mask(SECURE_NOROOT) | \
> ++				
> issecure_mask(SECURE_NO_SETUID_FIXUP) | \
> ++				 issecure_mask(SECURE_KEEP_CAPS) | \
> ++				
> issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))
> ++#define SECURE_ALL_LOCKS	(SECURE_ALL_BITS << 1)
> ++
> ++#endif /* _UAPI_LINUX_SECUREBITS_H */
> +diff --git a/lib/libcap/libcap.h b/lib/libcap/libcap.h
> +index 5751651..dd0a9cd 100644
> +--- a/lib/libcap/libcap.h
> ++++ b/lib/libcap/libcap.h
> +@@ -1,7 +1,5 @@
> + /*
> +- * Copyright (c) 1997 Andrew G Morgan <morgan@linux.kernel.org>
> +- *
> +- * See end of file for Log.
> ++ * Copyright (c) 1997 Andrew G Morgan <morgan@kernel.org>
> +  *
> +  * 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"
> 
> -=-=-=-=-=-=-=-=-=-=-=-
> 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/3616702
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe:
> https://lists.openembedded.org/g/openembedded-devel/unsub [
> anuj.mittal@intel.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
akuster808 Feb. 28, 2024, 2:05 p.m. UTC | #2
On 2/26/24 3:55 AM, Anuj Mittal wrote:
> On Mon, 2024-02-26 at 11:25 +0530, Hitendra Prajapati via
> lists.openembedded.org wrote:
>> Upstream-Status: Backport from
>> https://github.com/proftpd/proftpd/commit/743330874ee19dfcf2405827274015da0663bd2b
>>
>> Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
>> ---
>>   .../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 <tj@castaglia.org>
>> +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/743330874ee19dfcf240582727
>> 4015da0663bd2b]
> I think it'd be better to update the recipe to 1.3.6e maintenance
> release that already has this fix instead of carrying this patch.

I agree.

- armin
>
> http://proftpd.org/docs/RELEASE_NOTES-1.3.6e
>
> Thanks,
>
> Anuj
>
>> +CVE: CVE-2020-9272
>> +Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
>> +---
>> + 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 core@proftpd.org.
>> +@@ -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 <morgan@linux.kernel.org>
>> ++ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@kernel.org>
>> +  *
>> +  * 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 <morgan@linux.kernel.org>
>> +- *
>> +- * See end of file for Log.
>> ++ * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
>> +  *
>> +  * 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 <morgan@linux.kernel.org>
>> +- *
>> +- * See end of file for Log.
>> ++ * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
>> +  *
>> +  * 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 <morgan@linux.kernel.org>
>> +- *
>> +- * See end of file for Log.
>> ++ * Copyright (c) 1997,2007,2016 Andrew G Morgan <morgan@kernel.org>
>> +  *
>> +  * 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 <morgan@linux.kernel.org>
>> +- *
>> +- * See end of file for Log.
>> ++ * Copyright (c) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
>> +  *
>> +  * 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 <morgan@linux.kernel.org>
>> ++ * Copyright (c) 1997-8,2007,2011 Andrew G Morgan
>> <morgan@kernel.org>
>> +  *
>> +- * 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
>> <morgan@linux.kernel.org>
>> +- *
>> +- * 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 <morgan@linux.kernel.org>
>> ++ * Copyright (c) 1997-8,2007-8 Andrew G Morgan <morgan@kernel.org>
>> +  * Copyright (c) 1997 Andrew Main <zefram@dcs.warwick.ac.uk>
>> +  *
>> +- * 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 <morgan@linux.kernel.org>
>> ++ * Copyright (C) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
>> +  *
>> +  * 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 <serue@us.ibm.com>
>> ++ */
>> ++
>> ++#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 <morgan@kernel.org>
>> ++ * Alexander Kjeldaas <astor@guardian.no>
>> ++ * with help from Aleph1, Roland Buresund and Andrew Main.
>> ++ *
>> ++ * See here for the libcap library ("POSIX draft" compliance):
>> ++ *
>> ++ * http://www.kernel.org/pub/linux/libs/security/linux-privs/
>> ++ */
>> ++
>> ++#ifndef _UAPI_LINUX_CAPABILITY_H
>> ++#define _UAPI_LINUX_CAPABILITY_H
>> ++
>> ++#include <linux/types.h>
>> ++
>> ++struct task_struct;
>> ++
>> ++/* User-level do most of the mapping between kernel and user
>> ++   capabilities based on the version tag given by the kernel. The
>> ++   kernel might be somewhat backwards compatible, but don't bet on
>> ++   it. */
>> ++
>> ++/* Note, cap_t, is defined by POSIX (draft) to be an "opaque"
>> pointer to
>> ++   a set of three capability sets.  The transposition of 3*the
>> ++   following structure to such a composite is better handled in a
>> user
>> ++   library since the draft standard requires the use of malloc/free
>> ++   etc.. */
>> ++
>> ++#define _LINUX_CAPABILITY_VERSION_1  0x19980330
>> ++#define _LINUX_CAPABILITY_U32S_1     1
>> ++
>> ++#define _LINUX_CAPABILITY_VERSION_2  0x20071026  /* deprecated -
>> use v3 */
>> ++#define _LINUX_CAPABILITY_U32S_2     2
>> ++
>> ++#define _LINUX_CAPABILITY_VERSION_3  0x20080522
>> ++#define _LINUX_CAPABILITY_U32S_3     2
>> ++
>> ++typedef struct __user_cap_header_struct {
>> ++	__u32 version;
>> ++	int pid;
>> ++} __user *cap_user_header_t;
>> ++
>> ++typedef struct __user_cap_data_struct {
>> ++        __u32 effective;
>> ++        __u32 permitted;
>> ++        __u32 inheritable;
>> ++} __user *cap_user_data_t;
>> ++
>> ++
>> ++#define VFS_CAP_REVISION_MASK	0xFF000000
>> ++#define VFS_CAP_REVISION_SHIFT	24
>> ++#define VFS_CAP_FLAGS_MASK	~VFS_CAP_REVISION_MASK
>> ++#define VFS_CAP_FLAGS_EFFECTIVE	0x000001
>> ++
>> ++#define VFS_CAP_REVISION_1	0x01000000
>> ++#define VFS_CAP_U32_1           1
>> ++#define XATTR_CAPS_SZ_1         (sizeof(__le32)*(1 +
>> 2*VFS_CAP_U32_1))
>> ++
>> ++#define VFS_CAP_REVISION_2	0x02000000
>> ++#define VFS_CAP_U32_2           2
>> ++#define XATTR_CAPS_SZ_2         (sizeof(__le32)*(1 +
>> 2*VFS_CAP_U32_2))
>> ++
>> ++#define XATTR_CAPS_SZ           XATTR_CAPS_SZ_2
>> ++#define VFS_CAP_U32             VFS_CAP_U32_2
>> ++#define VFS_CAP_REVISION	VFS_CAP_REVISION_2
>> ++
>> ++struct vfs_cap_data {
>> ++	__le32 magic_etc;            /* Little endian */
>> ++	struct {
>> ++		__le32 permitted;    /* Little endian */
>> ++		__le32 inheritable;  /* Little endian */
>> ++	} data[VFS_CAP_U32];
>> ++};
>> ++
>> ++#ifndef __KERNEL__
>> ++
>> ++/*
>> ++ * Backwardly compatible definition for source code - trapped in a
>> ++ * 32-bit world. If you find you need this, please consider using
>> ++ * libcap to untrap yourself...
>> ++ */
>> ++#define _LINUX_CAPABILITY_VERSION  _LINUX_CAPABILITY_VERSION_1
>> ++#define _LINUX_CAPABILITY_U32S     _LINUX_CAPABILITY_U32S_1
>> ++
>> ++#endif
>> ++
>> ++
>> ++/**
>> ++ ** POSIX-draft defined capabilities.
>> ++ **/
>> ++
>> ++/* In a system with the [_POSIX_CHOWN_RESTRICTED] option defined,
>> this
>> ++   overrides the restriction of changing file ownership and group
>> ++   ownership. */
>> ++
>> ++#define CAP_CHOWN            0
>> ++
>> ++/* Override all DAC access, including ACL execute access if
>> ++   [_POSIX_ACL] is defined. Excluding DAC access covered by
>> ++   CAP_LINUX_IMMUTABLE. */
>> ++
>> ++#define CAP_DAC_OVERRIDE     1
>> ++
>> ++/* Overrides all DAC restrictions regarding read and search on
>> files
>> ++   and directories, including ACL restrictions if [_POSIX_ACL] is
>> ++   defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */
>> ++
>> ++#define CAP_DAC_READ_SEARCH  2
>> ++
>> ++/* Overrides all restrictions about allowed operations on files,
>> where
>> ++   file owner ID must be equal to the user ID, except where
>> CAP_FSETID
>> ++   is applicable. It doesn't override MAC and DAC restrictions. */
>> ++
>> ++#define CAP_FOWNER           3
>> ++
>> ++/* Overrides the following restrictions that the effective user ID
>> ++   shall match the file owner ID when setting the S_ISUID and
>> S_ISGID
>> ++   bits on that file; that the effective group ID (or one of the
>> ++   supplementary group IDs) shall match the file owner ID when
>> setting
>> ++   the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits
>> are
>> ++   cleared on successful return from chown(2) (not implemented). */
>> ++
>> ++#define CAP_FSETID           4
>> ++
>> ++/* Overrides the restriction that the real or effective user ID of
>> a
>> ++   process sending a signal must match the real or effective user
>> ID
>> ++   of the process receiving the signal. */
>> ++
>> ++#define CAP_KILL             5
>> ++
>> ++/* Allows setgid(2) manipulation */
>> ++/* Allows setgroups(2) */
>> ++/* Allows forged gids on socket credentials passing. */
>> ++
>> ++#define CAP_SETGID           6
>> ++
>> ++/* Allows set*uid(2) manipulation (including fsuid). */
>> ++/* Allows forged pids on socket credentials passing. */
>> ++
>> ++#define CAP_SETUID           7
>> ++
>> ++
>> ++/**
>> ++ ** Linux-specific capabilities
>> ++ **/
>> ++
>> ++/* Without VFS support for capabilities:
>> ++ *   Transfer any capability in your permitted set to any pid,
>> ++ *   remove any capability in your permitted set from any pid
>> ++ * With VFS support for capabilities (neither of above, but)
>> ++ *   Add any capability from current's capability bounding set
>> ++ *       to the current process' inheritable set
>> ++ *   Allow taking bits out of capability bounding set
>> ++ *   Allow modification of the securebits for a process
>> ++ */
>> ++
>> ++#define CAP_SETPCAP          8
>> ++
>> ++/* Allow modification of S_IMMUTABLE and S_APPEND file attributes
>> */
>> ++
>> ++#define CAP_LINUX_IMMUTABLE  9
>> ++
>> ++/* Allows binding to TCP/UDP sockets below 1024 */
>> ++/* Allows binding to ATM VCIs below 32 */
>> ++
>> ++#define CAP_NET_BIND_SERVICE 10
>> ++
>> ++/* Allow broadcasting, listen to multicast */
>> ++
>> ++#define CAP_NET_BROADCAST    11
>> ++
>> ++/* Allow interface configuration */
>> ++/* Allow administration of IP firewall, masquerading and accounting
>> */
>> ++/* Allow setting debug option on sockets */
>> ++/* Allow modification of routing tables */
>> ++/* Allow setting arbitrary process / process group ownership on
>> ++   sockets */
>> ++/* Allow binding to any address for transparent proxying (also via
>> NET_RAW) */
>> ++/* Allow setting TOS (type of service) */
>> ++/* Allow setting promiscuous mode */
>> ++/* Allow clearing driver statistics */
>> ++/* Allow multicasting */
>> ++/* Allow read/write of device-specific registers */
>> ++/* Allow activation of ATM control sockets */
>> ++
>> ++#define CAP_NET_ADMIN        12
>> ++
>> ++/* Allow use of RAW sockets */
>> ++/* Allow use of PACKET sockets */
>> ++/* Allow binding to any address for transparent proxying (also via
>> NET_ADMIN) */
>> ++
>> ++#define CAP_NET_RAW          13
>> ++
>> ++/* Allow locking of shared memory segments */
>> ++/* Allow mlock and mlockall (which doesn't really have anything to
>> do
>> ++   with IPC) */
>> ++
>> ++#define CAP_IPC_LOCK         14
>> ++
>> ++/* Override IPC ownership checks */
>> ++
>> ++#define CAP_IPC_OWNER        15
>> ++
>> ++/* Insert and remove kernel modules - modify kernel without limit
>> */
>> ++#define CAP_SYS_MODULE       16
>> ++
>> ++/* Allow ioperm/iopl access */
>> ++/* Allow sending USB messages to any device via /proc/bus/usb */
>> ++
>> ++#define CAP_SYS_RAWIO        17
>> ++
>> ++/* Allow use of chroot() */
>> ++
>> ++#define CAP_SYS_CHROOT       18
>> ++
>> ++/* Allow ptrace() of any process */
>> ++
>> ++#define CAP_SYS_PTRACE       19
>> ++
>> ++/* Allow configuration of process accounting */
>> ++
>> ++#define CAP_SYS_PACCT        20
>> ++
>> ++/* Allow configuration of the secure attention key */
>> ++/* Allow administration of the random device */
>> ++/* Allow examination and configuration of disk quotas */
>> ++/* Allow setting the domainname */
>> ++/* Allow setting the hostname */
>> ++/* Allow calling bdflush() */
>> ++/* Allow mount() and umount(), setting up new smb connection */
>> ++/* Allow some autofs root ioctls */
>> ++/* Allow nfsservctl */
>> ++/* Allow VM86_REQUEST_IRQ */
>> ++/* Allow to read/write pci config on alpha */
>> ++/* Allow irix_prctl on mips (setstacksize) */
>> ++/* Allow flushing all cache on m68k (sys_cacheflush) */
>> ++/* Allow removing semaphores */
>> ++/* Used instead of CAP_CHOWN to "chown" IPC message queues,
>> semaphores
>> ++   and shared memory */
>> ++/* Allow locking/unlocking of shared memory segment */
>> ++/* Allow turning swap on/off */
>> ++/* Allow forged pids on socket credentials passing */
>> ++/* Allow setting readahead and flushing buffers on block devices */
>> ++/* Allow setting geometry in floppy driver */
>> ++/* Allow turning DMA on/off in xd driver */
>> ++/* Allow administration of md devices (mostly the above, but some
>> ++   extra ioctls) */
>> ++/* Allow tuning the ide driver */
>> ++/* Allow access to the nvram device */
>> ++/* Allow administration of apm_bios, serial and bttv (TV) device */
>> ++/* Allow manufacturer commands in isdn CAPI support driver */
>> ++/* Allow reading non-standardized portions of pci configuration
>> space */
>> ++/* Allow DDI debug ioctl on sbpcd driver */
>> ++/* Allow setting up serial ports */
>> ++/* Allow sending raw qic-117 commands */
>> ++/* Allow enabling/disabling tagged queuing on SCSI controllers and
>> sending
>> ++   arbitrary SCSI commands */
>> ++/* Allow setting encryption key on loopback filesystem */
>> ++/* Allow setting zone reclaim policy */
>> ++
>> ++#define CAP_SYS_ADMIN        21
>> ++
>> ++/* Allow use of reboot() */
>> ++
>> ++#define CAP_SYS_BOOT         22
>> ++
>> ++/* Allow raising priority and setting priority on other (different
>> ++   UID) processes */
>> ++/* Allow use of FIFO and round-robin (realtime) scheduling on own
>> ++   processes and setting the scheduling algorithm used by another
>> ++   process. */
>> ++/* Allow setting cpu affinity on other processes */
>> ++
>> ++#define CAP_SYS_NICE         23
>> ++
>> ++/* Override resource limits. Set resource limits. */
>> ++/* Override quota limits. */
>> ++/* Override reserved space on ext2 filesystem */
>> ++/* Modify data journaling mode on ext3 filesystem (uses journaling
>> ++   resources) */
>> ++/* NOTE: ext2 honors fsuid when checking for resource overrides, so
>> ++   you can override using fsuid too */
>> ++/* Override size restrictions on IPC message queues */
>> ++/* Allow more than 64hz interrupts from the real-time clock */
>> ++/* Override max number of consoles on console allocation */
>> ++/* Override max number of keymaps */
>> ++
>> ++#define CAP_SYS_RESOURCE     24
>> ++
>> ++/* Allow manipulation of system clock */
>> ++/* Allow irix_stime on mips */
>> ++/* Allow setting the real-time clock */
>> ++
>> ++#define CAP_SYS_TIME         25
>> ++
>> ++/* Allow configuration of tty devices */
>> ++/* Allow vhangup() of tty */
>> ++
>> ++#define CAP_SYS_TTY_CONFIG   26
>> ++
>> ++/* Allow the privileged aspects of mknod() */
>> ++
>> ++#define CAP_MKNOD            27
>> ++
>> ++/* Allow taking of leases on files */
>> ++
>> ++#define CAP_LEASE            28
>> ++
>> ++/* Allow writing the audit log via unicast netlink socket */
>> ++
>> ++#define CAP_AUDIT_WRITE      29
>> ++
>> ++/* Allow configuration of audit via unicast netlink socket */
>> ++
>> ++#define CAP_AUDIT_CONTROL    30
>> ++
>> ++#define CAP_SETFCAP	     31
>> ++
>> ++/* Override MAC access.
>> ++   The base kernel enforces no MAC policy.
>> ++   An LSM may enforce a MAC policy, and if it does and it chooses
>> ++   to implement capability based overrides of that policy, this is
>> ++   the capability it should use to do so. */
>> ++
>> ++#define CAP_MAC_OVERRIDE     32
>> ++
>> ++/* Allow MAC configuration or state changes.
>> ++   The base kernel requires no MAC configuration.
>> ++   An LSM may enforce a MAC policy, and if it does and it chooses
>> ++   to implement capability based checks on modifications to that
>> ++   policy or the data required to maintain it, this is the
>> ++   capability it should use to do so. */
>> ++
>> ++#define CAP_MAC_ADMIN        33
>> ++
>> ++/* Allow configuring the kernel's syslog (printk behaviour) */
>> ++
>> ++#define CAP_SYSLOG           34
>> ++
>> ++/* Allow triggering something that will wake the system */
>> ++
>> ++#define CAP_WAKE_ALARM            35
>> ++
>> ++/* Allow preventing system suspends */
>> ++
>> ++#define CAP_BLOCK_SUSPEND    36
>> ++
>> ++/* Allow reading the audit log via multicast netlink socket */
>> ++
>> ++#define CAP_AUDIT_READ       37
>> ++
>> ++
>> ++#define CAP_LAST_CAP         CAP_AUDIT_READ
>> ++
>> ++#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
>> ++
>> ++/*
>> ++ * Bit location of each capability (used by user-space library and
>> kernel)
>> ++ */
>> ++
>> ++#define CAP_TO_INDEX(x)     ((x) >> 5)        /* 1 << 5 == bits in
>> __u32 */
>> ++#define CAP_TO_MASK(x)      (1 << ((x) & 31)) /* mask for indexed
>> __u32 */
>> ++
>> ++
>> ++#endif /* _UAPI_LINUX_CAPABILITY_H */
>> +diff --git a/lib/libcap/include/uapi/linux/prctl.h
>> b/lib/libcap/include/uapi/linux/prctl.h
>> +new file mode 100644
>> +index 0000000..a8d0759
>> +--- /dev/null
>> ++++ b/lib/libcap/include/uapi/linux/prctl.h
>> +@@ -0,0 +1,200 @@
>> ++#ifndef _LINUX_PRCTL_H
>> ++#define _LINUX_PRCTL_H
>> ++
>> ++#include <linux/types.h>
>> ++
>> ++/* Values to pass as first argument to prctl() */
>> ++
>> ++#define PR_SET_PDEATHSIG  1  /* Second arg is a signal */
>> ++#define PR_GET_PDEATHSIG  2  /* Second arg is a ptr to return the
>> signal */
>> ++
>> ++/* Get/set current->mm->dumpable */
>> ++#define PR_GET_DUMPABLE   3
>> ++#define PR_SET_DUMPABLE   4
>> ++
>> ++/* Get/set unaligned access control bits (if meaningful) */
>> ++#define PR_GET_UNALIGN	  5
>> ++#define PR_SET_UNALIGN	  6
>> ++# define PR_UNALIGN_NOPRINT	1	/* silently fix up unaligned
>> user accesses */
>> ++# define PR_UNALIGN_SIGBUS	2	/* generate SIGBUS on
>> unaligned user access */
>> ++
>> ++/* Get/set whether or not to drop capabilities on setuid() away
>> from
>> ++ * uid 0 (as per security/commoncap.c) */
>> ++#define PR_GET_KEEPCAPS   7
>> ++#define PR_SET_KEEPCAPS   8
>> ++
>> ++/* Get/set floating-point emulation control bits (if meaningful) */
>> ++#define PR_GET_FPEMU  9
>> ++#define PR_SET_FPEMU 10
>> ++# define PR_FPEMU_NOPRINT	1	/* silently emulate fp
>> operations accesses */
>> ++# define PR_FPEMU_SIGFPE	2	/* don't emulate fp
>> operations, send SIGFPE instead */
>> ++
>> ++/* Get/set floating-point exception mode (if meaningful) */
>> ++#define PR_GET_FPEXC	11
>> ++#define PR_SET_FPEXC	12
>> ++# define PR_FP_EXC_SW_ENABLE	0x80	/* Use FPEXC for FP
>> exception enables */
>> ++# define PR_FP_EXC_DIV		0x010000	/* floating
>> point divide by zero */
>> ++# define PR_FP_EXC_OVF		0x020000	/* floating
>> point overflow */
>> ++# define PR_FP_EXC_UND		0x040000	/* floating
>> point underflow */
>> ++# define PR_FP_EXC_RES		0x080000	/* floating
>> point inexact result */
>> ++# define PR_FP_EXC_INV		0x100000	/* floating
>> point invalid operation */
>> ++# define PR_FP_EXC_DISABLED	0	/* FP exceptions disabled */
>> ++# define PR_FP_EXC_NONRECOV	1	/* async non-recoverable
>> exc. mode */
>> ++# define PR_FP_EXC_ASYNC	2	/* async recoverable
>> exception mode */
>> ++# define PR_FP_EXC_PRECISE	3	/* precise exception mode */
>> ++
>> ++/* Get/set whether we use statistical process timing or accurate
>> timestamp
>> ++ * based process timing */
>> ++#define PR_GET_TIMING   13
>> ++#define PR_SET_TIMING   14
>> ++# define PR_TIMING_STATISTICAL  0       /* Normal, traditional,
>> ++                                                   statistical
>> process timing */
>> ++# define PR_TIMING_TIMESTAMP    1       /* Accurate timestamp based
>> ++                                                   process timing
>> */
>> ++
>> ++#define PR_SET_NAME    15		/* Set process name */
>> ++#define PR_GET_NAME    16		/* Get process name */
>> ++
>> ++/* Get/set process endian */
>> ++#define PR_GET_ENDIAN	19
>> ++#define PR_SET_ENDIAN	20
>> ++# define PR_ENDIAN_BIG		0
>> ++# define PR_ENDIAN_LITTLE	1	/* True little endian mode
>> */
>> ++# define PR_ENDIAN_PPC_LITTLE	2	/* "PowerPC" pseudo little
>> endian */
>> ++
>> ++/* Get/set process seccomp mode */
>> ++#define PR_GET_SECCOMP	21
>> ++#define PR_SET_SECCOMP	22
>> ++
>> ++/* Get/set the capability bounding set (as per
>> security/commoncap.c) */
>> ++#define PR_CAPBSET_READ 23
>> ++#define PR_CAPBSET_DROP 24
>> ++
>> ++/* Get/set the process' ability to use the timestamp counter
>> instruction */
>> ++#define PR_GET_TSC 25
>> ++#define PR_SET_TSC 26
>> ++# define PR_TSC_ENABLE		1	/* allow the use of
>> the timestamp counter */
>> ++# define PR_TSC_SIGSEGV		2	/* throw a SIGSEGV
>> instead of reading the TSC */
>> ++
>> ++/* Get/set securebits (as per security/commoncap.c) */
>> ++#define PR_GET_SECUREBITS 27
>> ++#define PR_SET_SECUREBITS 28
>> ++
>> ++/*
>> ++ * Get/set the timerslack as used by poll/select/nanosleep
>> ++ * A value of 0 means "use default"
>> ++ */
>> ++#define PR_SET_TIMERSLACK 29
>> ++#define PR_GET_TIMERSLACK 30
>> ++
>> ++#define PR_TASK_PERF_EVENTS_DISABLE		31
>> ++#define PR_TASK_PERF_EVENTS_ENABLE		32
>> ++
>> ++/*
>> ++ * Set early/late kill mode for hwpoison memory corruption.
>> ++ * This influences when the process gets killed on a memory
>> corruption.
>> ++ */
>> ++#define PR_MCE_KILL	33
>> ++# define PR_MCE_KILL_CLEAR   0
>> ++# define PR_MCE_KILL_SET     1
>> ++
>> ++# define PR_MCE_KILL_LATE    0
>> ++# define PR_MCE_KILL_EARLY   1
>> ++# define PR_MCE_KILL_DEFAULT 2
>> ++
>> ++#define PR_MCE_KILL_GET 34
>> ++
>> ++/*
>> ++ * Tune up process memory map specifics.
>> ++ */
>> ++#define PR_SET_MM		35
>> ++# define PR_SET_MM_START_CODE		1
>> ++# define PR_SET_MM_END_CODE		2
>> ++# define PR_SET_MM_START_DATA		3
>> ++# define PR_SET_MM_END_DATA		4
>> ++# define PR_SET_MM_START_STACK		5
>> ++# define PR_SET_MM_START_BRK		6
>> ++# define PR_SET_MM_BRK			7
>> ++# define PR_SET_MM_ARG_START		8
>> ++# define PR_SET_MM_ARG_END		9
>> ++# define PR_SET_MM_ENV_START		10
>> ++# define PR_SET_MM_ENV_END		11
>> ++# define PR_SET_MM_AUXV			12
>> ++# define PR_SET_MM_EXE_FILE		13
>> ++# define PR_SET_MM_MAP			14
>> ++# define PR_SET_MM_MAP_SIZE		15
>> ++
>> ++/*
>> ++ * This structure provides new memory descriptor
>> ++ * map which mostly modifies /proc/pid/stat[m]
>> ++ * output for a task. This mostly done in a
>> ++ * sake of checkpoint/restore functionality.
>> ++ */
>> ++struct prctl_mm_map {
>> ++	__u64	start_code;		/* code section bounds */
>> ++	__u64	end_code;
>> ++	__u64	start_data;		/* data section bounds */
>> ++	__u64	end_data;
>> ++	__u64	start_brk;		/* heap for brk() syscall */
>> ++	__u64	brk;
>> ++	__u64	start_stack;		/* stack starts at */
>> ++	__u64	arg_start;		/* command line arguments
>> bounds */
>> ++	__u64	arg_end;
>> ++	__u64	env_start;		/* environment variables
>> bounds */
>> ++	__u64	env_end;
>> ++	__u64	*auxv;			/* auxiliary vector */
>> ++	__u32	auxv_size;		/* vector size */
>> ++	__u32	exe_fd;			/* /proc/$pid/exe
>> link file */
>> ++};
>> ++
>> ++/*
>> ++ * Set specific pid that is allowed to ptrace the current task.
>> ++ * A value of 0 mean "no process".
>> ++ */
>> ++#define PR_SET_PTRACER 0x59616d61
>> ++# define PR_SET_PTRACER_ANY ((unsigned long)-1)
>> ++
>> ++#define PR_SET_CHILD_SUBREAPER	36
>> ++#define PR_GET_CHILD_SUBREAPER	37
>> ++
>> ++/*
>> ++ * If no_new_privs is set, then operations that grant new
>> privileges (i.e.
>> ++ * execve) will either fail or not grant them.  This affects
>> suid/sgid,
>> ++ * file capabilities, and LSMs.
>> ++ *
>> ++ * Operations that merely manipulate or drop existing privileges
>> (setresuid,
>> ++ * capset, etc.) will still work.  Drop those privileges if you
>> want them gone.
>> ++ *
>> ++ * Changing LSM security domain is considered a new privilege.  So,
>> for example,
>> ++ * asking selinux for a specific new context (e.g. with runcon)
>> will result
>> ++ * in execve returning -EPERM.
>> ++ *
>> ++ * See Documentation/prctl/no_new_privs.txt for more details.
>> ++ */
>> ++#define PR_SET_NO_NEW_PRIVS	38
>> ++#define PR_GET_NO_NEW_PRIVS	39
>> ++
>> ++#define PR_GET_TID_ADDRESS	40
>> ++
>> ++#define PR_SET_THP_DISABLE	41
>> ++#define PR_GET_THP_DISABLE	42
>> ++
>> ++/*
>> ++ * Tell the kernel to start/stop helping userspace manage bounds
>> tables.
>> ++ */
>> ++#define PR_MPX_ENABLE_MANAGEMENT  43
>> ++#define PR_MPX_DISABLE_MANAGEMENT 44
>> ++
>> ++#define PR_SET_FP_MODE		45
>> ++#define PR_GET_FP_MODE		46
>> ++# define PR_FP_MODE_FR		(1 << 0)	/* 64b FP
>> registers */
>> ++# define PR_FP_MODE_FRE		(1 << 1)	/* 32b
>> compatibility */
>> ++
>> ++/* Control the ambient capability set */
>> ++#define PR_CAP_AMBIENT			47
>> ++# define PR_CAP_AMBIENT_IS_SET		1
>> ++# define PR_CAP_AMBIENT_RAISE		2
>> ++# define PR_CAP_AMBIENT_LOWER		3
>> ++# define PR_CAP_AMBIENT_CLEAR_ALL	4
>> ++
>> ++#endif /* _LINUX_PRCTL_H */
>> +diff --git a/lib/libcap/include/uapi/linux/securebits.h
>> b/lib/libcap/include/uapi/linux/securebits.h
>> +new file mode 100644
>> +index 0000000..35ac35c
>> +--- /dev/null
>> ++++ b/lib/libcap/include/uapi/linux/securebits.h
>> +@@ -0,0 +1,60 @@
>> ++#ifndef _UAPI_LINUX_SECUREBITS_H
>> ++#define _UAPI_LINUX_SECUREBITS_H
>> ++
>> ++/* Each securesetting is implemented using two bits. One bit
>> specifies
>> ++   whether the setting is on or off. The other bit specify whether
>> the
>> ++   setting is locked or not. A setting which is locked cannot be
>> ++   changed from user-level. */
>> ++#define issecure_mask(X)	(1 << (X))
>> ++
>> ++#define SECUREBITS_DEFAULT 0x00000000
>> ++
>> ++/* When set UID 0 has no special privileges. When unset, we support
>> ++   inheritance of root-permissions and suid-root executable under
>> ++   compatibility mode. We raise the effective and inheritable
>> bitmasks
>> ++   *of the executable file* if the effective uid of the new process
>> is
>> ++   0. If the real uid is 0, we raise the effective (legacy) bit of
>> the
>> ++   executable file. */
>> ++#define SECURE_NOROOT			0
>> ++#define SECURE_NOROOT_LOCKED		1  /* make bit-0 immutable
>> */
>> ++
>> ++#define SECBIT_NOROOT		(issecure_mask(SECURE_NOROOT))
>> ++#define
>> SECBIT_NOROOT_LOCKED	(issecure_mask(SECURE_NOROOT_LOCKED))
>> ++
>> ++/* When set, setuid to/from uid 0 does not trigger capability-
>> "fixup".
>> ++   When unset, to provide compatiblility with old programs relying
>> on
>> ++   set*uid to gain/lose privilege, transitions to/from uid 0 cause
>> ++   capabilities to be gained/lost. */
>> ++#define SECURE_NO_SETUID_FIXUP		2
>> ++#define SECURE_NO_SETUID_FIXUP_LOCKED	3  /* make bit-2 immutable
>> */
>> ++
>> ++#define
>> SECBIT_NO_SETUID_FIXUP	(issecure_mask(SECURE_NO_SETUID_FIXUP))
>> ++#define SECBIT_NO_SETUID_FIXUP_LOCKED \
>> ++			(issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED
>> ))
>> ++
>> ++/* When set, a process can retain its capabilities even after
>> ++   transitioning to a non-root user (the set-uid fixup suppressed
>> by
>> ++   bit 2). Bit-4 is cleared when a process calls exec(); setting
>> both
>> ++   bit 4 and 5 will create a barrier through exec that no exec()'d
>> ++   child can use this feature again. */
>> ++#define SECURE_KEEP_CAPS		4
>> ++#define SECURE_KEEP_CAPS_LOCKED		5  /* make bit-4
>> immutable */
>> ++
>> ++#define SECBIT_KEEP_CAPS	(issecure_mask(SECURE_KEEP_CAPS))
>> ++#define SECBIT_KEEP_CAPS_LOCKED
>> (issecure_mask(SECURE_KEEP_CAPS_LOCKED))
>> ++
>> ++/* When set, a process cannot add new capabilities to its ambient
>> set. */
>> ++#define SECURE_NO_CAP_AMBIENT_RAISE		6
>> ++#define SECURE_NO_CAP_AMBIENT_RAISE_LOCKED	7  /* make bit-6
>> immutable */
>> ++
>> ++#define SECBIT_NO_CAP_AMBIENT_RAISE
>> (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))
>> ++#define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED \
>> ++			(issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_L
>> OCKED))
>> ++
>> ++#define
>> SECURE_ALL_BITS		(issecure_mask(SECURE_NOROOT) | \
>> ++				
>> issecure_mask(SECURE_NO_SETUID_FIXUP) | \
>> ++				 issecure_mask(SECURE_KEEP_CAPS) | \
>> ++				
>> issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))
>> ++#define SECURE_ALL_LOCKS	(SECURE_ALL_BITS << 1)
>> ++
>> ++#endif /* _UAPI_LINUX_SECUREBITS_H */
>> +diff --git a/lib/libcap/libcap.h b/lib/libcap/libcap.h
>> +index 5751651..dd0a9cd 100644
>> +--- a/lib/libcap/libcap.h
>> ++++ b/lib/libcap/libcap.h
>> +@@ -1,7 +1,5 @@
>> + /*
>> +- * Copyright (c) 1997 Andrew G Morgan <morgan@linux.kernel.org>
>> +- *
>> +- * See end of file for Log.
>> ++ * Copyright (c) 1997 Andrew G Morgan <morgan@kernel.org>
>> +  *
>> +  * 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"
>>
>>
>>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#109030): https://lists.openembedded.org/g/openembedded-devel/message/109030
> Mute This Topic: https://lists.openembedded.org/mt/104577724/3616698
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [akuster808@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
diff mbox series

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 <tj@castaglia.org>
+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 <hprajapati@mvista.com>
+---
+ 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 core@proftpd.org.
+@@ -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 <morgan@linux.kernel.org>
++ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@kernel.org>
+  *
+  * 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 <morgan@linux.kernel.org>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
+  *
+  * 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 <morgan@linux.kernel.org>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
+  *
+  * 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 <morgan@linux.kernel.org>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997,2007,2016 Andrew G Morgan <morgan@kernel.org>
+  *
+  * 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 <morgan@linux.kernel.org>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
+  *
+  * 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 <morgan@linux.kernel.org>
++ * Copyright (c) 1997-8,2007,2011 Andrew G Morgan <morgan@kernel.org>
+  *
+- * 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   <morgan@linux.kernel.org>
+- *
+- * 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 <morgan@linux.kernel.org>
++ * Copyright (c) 1997-8,2007-8 Andrew G Morgan <morgan@kernel.org>
+  * Copyright (c) 1997 Andrew Main <zefram@dcs.warwick.ac.uk>
+  *
+- * 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 <morgan@linux.kernel.org>
++ * Copyright (C) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
+  *
+  * 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 <serue@us.ibm.com>
++ */
++
++#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 <morgan@kernel.org>
++ * Alexander Kjeldaas <astor@guardian.no>
++ * 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 <morgan@linux.kernel.org>
+- *
+- * See end of file for Log.
++ * Copyright (c) 1997 Andrew G Morgan <morgan@kernel.org>
+  *
+  * 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"