From patchwork Mon Feb 26 05:55:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hitendra Prajapati X-Patchwork-Id: 40064 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33D68C48BF6 for ; Mon, 26 Feb 2024 05:55:37 +0000 (UTC) Received: from mail-pf1-f174.google.com (mail-pf1-f174.google.com [209.85.210.174]) by mx.groups.io with SMTP id smtpd.web10.14989.1708926934150095011 for ; Sun, 25 Feb 2024 21:55:34 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@mvista.com header.s=google header.b=cA6Dtlxc; spf=pass (domain: mvista.com, ip: 209.85.210.174, mailfrom: hprajapati@mvista.com) Received: by mail-pf1-f174.google.com with SMTP id d2e1a72fcca58-6e457fab0e2so1604467b3a.0 for ; Sun, 25 Feb 2024 21:55:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mvista.com; s=google; t=1708926933; x=1709531733; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=qL05Sj6IT5fxuyhDO00QfoVRvNWPogw/eRezmtX2lv0=; b=cA6Dtlxcsk0A39P0xokW99iSoW4KzuGrdChJVUtng1PNzQRHX/3nBmpXkRGbgFrWrk HzRP6+7ZFpuMUmgp8CgAbkhPZ3q9ZCIpD/bbkWHIJ0GqSGGWT2wg1ezTnU7MFgc3wBnB U95xaFMh7lS3BwWl2ndiGzmw0DpYJb/QbkkfU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708926933; x=1709531733; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=qL05Sj6IT5fxuyhDO00QfoVRvNWPogw/eRezmtX2lv0=; b=KqUq/2MwOauwNYZ6xFNeoR05gMxaUMwNARC0lE4LheXRrBEZA48Hcmw0oE24ut7tgy 7UlwWfJBUZs/zY6u4K5BuIL/epbMPLlLj2KmZSwISv1c5gkdeNNlJnp9jMW+XtGJI4f4 5Sj7iPGpvE8qV2vk8jJe3h6uq1E4+6AiMpIRD/D5+NbDm5rCccWpBvylhMcIYCd0zpMF k8w2H7Q870QNOPrA+jRVUwvx/TUQwzSbXz5uv+ZpuWHopkRTYT9aUoAJzvFYV1l9IZIw 8qlFHBquZZwIxn3dp5Ns3Q41PplkLBTJvR8641bFkWIzWpQguwRFvAOwy0TfxvFwW2Bj RvqQ== X-Gm-Message-State: AOJu0Yxkt6OXV1FVGXOLa1S61KFYRrHYfdASx1b78eEGRuxwF/5A624j GpmMlNXZ3QxfjdiIhUxbwFxFUiaVcJskDgBS0VgZup9Wd2k5J0AnJJBc83rJEtTKvySwUS9d5lC H X-Google-Smtp-Source: AGHT+IGgfUpZbv5ZKYtdakbqyM1hXWQm55gmLXno4KwRwK5STB9y3d3msiYejGlEuyVGZkmuIa0www== X-Received: by 2002:a05:6a00:9293:b0:6e5:32e9:2954 with SMTP id jw19-20020a056a00929300b006e532e92954mr1439051pfb.16.1708926931994; Sun, 25 Feb 2024 21:55:31 -0800 (PST) Received: from MVIN00016.mvista.com ([150.129.170.198]) by smtp.gmail.com with ESMTPSA id fn11-20020a056a002fcb00b006e0737f2bafsm3168482pfb.45.2024.02.25.21.55.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Feb 2024 21:55:31 -0800 (PST) From: Hitendra Prajapati To: openembedded-devel@lists.openembedded.org Cc: Hitendra Prajapati Subject: [meta-networking][dunfell][PATCH] proftpd: fix CVE-2020-9272 Out-of-bounds read Date: Mon, 26 Feb 2024 11:25:25 +0530 Message-Id: <20240226055525.30105-1-hprajapati@mvista.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 26 Feb 2024 05:55:37 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/109028 Upstream-Status: Backport from https://github.com/proftpd/proftpd/commit/743330874ee19dfcf2405827274015da0663bd2b Signed-off-by: Hitendra Prajapati --- .../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 +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 +--- + 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 " +- @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 ++ * Copyright (c) 1997-8 Andrew G. Morgan + * + * 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 +- * +- * See end of file for Log. ++ * Copyright (c) 1997-8 Andrew G Morgan + * + * 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 +- * +- * See end of file for Log. ++ * Copyright (c) 1997-8 Andrew G Morgan + * + * 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; iu[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; setbytes[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 +- * +- * See end of file for Log. ++ * Copyright (c) 1997,2007,2016 Andrew G Morgan + * + * This file deals with setting capabilities on files. + */ + ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * 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 +- * +- * See end of file for Log. ++ * Copyright (c) 1997-8,2008 Andrew G. Morgan + * + * 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 ++ * Copyright (c) 1997-8,2007,2011 Andrew G Morgan + * +- * 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 ++ + #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 +- * +- * This file contains the system calls for getting and setting +- * capabilities +- */ +- +-#include "libcap.h" +-#define __LIBRARY__ +-#include +- +-/* +- * $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 ++ * Copyright (c) 1997-8,2007-8 Andrew G Morgan + * Copyright (c) 1997 Andrew Main + * +- * See end of file for Log. +- * + * This file deals with exchanging internal and textual + * representations of capability sets. + */ + ++#define _GNU_SOURCE ++#include ++ + #define LIBCAP_PLEASE_INCLUDE_ARRAY + #include "libcap.h" + + #include +-#include ++#include + + /* 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 @@ + /* + * + * +- * + * Copyright (C) 1997 Aleph One +- * Copyright (C) 1997-8 Andrew G. Morgan ++ * Copyright (C) 1997-8,2008 Andrew G. Morgan + * + * defunct POSIX.1e Standard: 25.2 Capabilities + */ +@@ -20,8 +19,13 @@ extern "C" { + * information for the user library. + */ + +-#define _LINUX_FS_H + #include ++#include ++#include ++ ++#ifndef __user ++#define __user ++#endif + #include + + /* +@@ -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 @@ ++/* ++ * ++ * Copyright (C) 2010 Serge Hallyn ++ */ ++ ++#ifndef _SYS_SECUREBITS_H ++#define _SYS_SECUREBITS_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#ifndef __user ++#define __user ++#endif ++#include ++ ++#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 ++ * ++ * Andrew G. Morgan ++ * Alexander Kjeldaas ++ * 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 ++ ++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 ++ ++/* 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 +- * +- * See end of file for Log. ++ * Copyright (c) 1997 Andrew G Morgan + * + * This file contains internal definitions for the various functions in + * this small capability library. +@@ -14,19 +12,70 @@ + #include + #include + #include ++#include + #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 does not support library ++# error file "libcap.h" --> fix and recompile libcap ++ ++#elif !defined(_LINUX_CAPABILITY_VERSION_2) ++ ++# warning Kernel 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 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 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 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 +-# 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"