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]] -=-=-=-=-=-=-=-=-=-=-=-
