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

-=-=-=-=-=-=-=-=-=-=-=-
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/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to