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