- add 0001-Improve-the-usage-and-diagnostic-message-for-setcap.patch

0002-No-longer-need-the-Go-build-tag-allthreadssyscall.patch
  0003-Minor-fixes-for-cap-package-documentation.patch
  0004-checkpoint.patch
  0005-Clean-up-the-exit-status-to-match-other-binaries.patch
  0006-People-keep-emailing-me-about-the-license-for-libcap.patch
  0007-Augment-NOPRIV-libcap-mode-with-the-sticky-NO_NEW_PR.patch

OBS-URL: https://build.opensuse.org/package/show/Base:System/libcap?expand=0&rev=49
This commit is contained in:
Dirk Mueller 2021-01-04 19:31:04 +00:00 committed by Git OBS Bridge
parent 60c579967a
commit 2db9681bdf
9 changed files with 895 additions and 0 deletions

View File

@ -0,0 +1,138 @@
From 87514ed4dcf2c1778cd9e405c48a0635551c78af Mon Sep 17 00:00:00 2001
From: "Andrew G. Morgan" <morgan@kernel.org>
Date: Sun, 20 Dec 2020 16:27:13 -0800
Subject: [PATCH 1/7] Improve the usage and diagnostic message for setcap
Also, explicitly support -h rather than fail over to display the usage
info.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
---
progs/setcap.c | 44 ++++++++++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/progs/setcap.c b/progs/setcap.c
index 442685d..f675cdd 100644
--- a/progs/setcap.c
+++ b/progs/setcap.c
@@ -11,15 +11,23 @@
#include <sys/capability.h>
#include <unistd.h>
-static void usage(void)
+static void usage(int status)
{
fprintf(stderr,
- "usage: setcap [-q] [-v] [-n <rootid>] (-r|-|<caps>) <filename> "
+ "usage: setcap [-h] [-q] [-v] [-n <rootid>] (-r|-|<caps>) <filename> "
"[ ... (-r|-|<capsN>) <filenameN> ]\n"
"\n"
" Note <filename> must be a regular (non-symlink) file.\n"
+ " -r remove capability from file\n"
+ " - read capability text from stdin\n"
+ " <capsN> cap_from_text(3) formatted file capability\n"
+ "\n"
+ " -h this message and exit status 0\n"
+ " -q quietly\n"
+ " -v validate supplied capability matches file\n"
+ " -n <rootid> write a user namespace limited capability\n"
);
- exit(1);
+ exit(status);
}
#define MAXCAP 2048
@@ -65,8 +73,8 @@ int main(int argc, char **argv)
cap_value_t capflag;
uid_t rootid = 0, f_rootid;
- if (argc < 3) {
- usage();
+ if (argc < 2) {
+ usage(1);
}
mycaps = cap_get_proc();
@@ -83,6 +91,9 @@ int main(int argc, char **argv)
quiet = 1;
continue;
}
+ if (!strcmp(*argv, "-h")) {
+ usage(0);
+ }
if (!strcmp(*argv, "-v")) {
verify = 1;
continue;
@@ -107,7 +118,7 @@ int main(int argc, char **argv)
if (!strcmp(*argv,"-")) {
retval = read_caps(quiet, *argv, buffer);
if (retval)
- usage();
+ usage(1);
text = buffer;
} else {
text = *argv;
@@ -116,7 +127,7 @@ int main(int argc, char **argv)
cap_d = cap_from_text(text);
if (cap_d == NULL) {
perror("fatal error");
- usage();
+ usage(1);
}
if (cap_set_nsowner(cap_d, rootid)) {
perror("unable to set nsowner");
@@ -134,7 +145,7 @@ int main(int argc, char **argv)
}
if (--argc <= 0)
- usage();
+ usage(1);
/*
* Set the filesystem capability for this file.
*/
@@ -194,6 +205,7 @@ int main(int argc, char **argv)
if (retval != 0) {
int explained = 0;
int oerrno = errno;
+ int somebits = 0;
#ifdef linux
cap_value_t cap;
cap_flag_value_t per_state;
@@ -201,24 +213,28 @@ int main(int argc, char **argv)
for (cap = 0;
cap_get_flag(cap_d, cap, CAP_PERMITTED, &per_state) != -1;
cap++) {
- cap_flag_value_t inh_state, eff_state;
+ cap_flag_value_t inh_state, eff_state, combined;
cap_get_flag(cap_d, cap, CAP_INHERITABLE, &inh_state);
cap_get_flag(cap_d, cap, CAP_EFFECTIVE, &eff_state);
- if ((inh_state | per_state) != eff_state) {
- fprintf(stderr, "NOTE: Under Linux, effective file capabilities must either be empty, or\n"
- " exactly match the union of selected permitted and inheritable bits.\n");
+ combined = (inh_state | per_state);
+ somebits |= !!eff_state;
+ if (combined != eff_state) {
explained = 1;
break;
}
}
+ if (somebits && explained) {
+ fprintf(stderr, "NOTE: Under Linux, effective file capabilities must either be empty, or\n"
+ " exactly match the union of selected permitted and inheritable bits.\n");
+ }
#endif /* def linux */
-
+
fprintf(stderr,
"Failed to set capabilities on file `%s' (%s)\n",
argv[0], strerror(oerrno));
if (!explained) {
- usage();
+ usage(1);
}
}
}
--
2.29.2

View File

@ -0,0 +1,103 @@
From 3633ca228671e2ddd9e115e74e09eea50ca8ad09 Mon Sep 17 00:00:00 2001
From: "Andrew G. Morgan" <morgan@kernel.org>
Date: Tue, 22 Dec 2020 20:03:54 -0800
Subject: [PATCH 2/7] No longer need the Go build tag allthreadssyscall.
Go 1.16 release branch contains the syscall.AllThreadsSyscall now,
so use the Go release tag to identify a build environment that supports
this feature.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
---
Make.Rules | 4 ----
cap/cap.go | 13 +++++--------
go/Makefile | 8 ++++----
psx/psx.go | 2 +-
4 files changed, 10 insertions(+), 17 deletions(-)
diff --git a/Make.Rules b/Make.Rules
index 3107c94..1b3d780 100644
--- a/Make.Rules
+++ b/Make.Rules
@@ -113,10 +113,6 @@ CGO_CFLAGS := -I$(topdir)/libcap/include
CGO_LDFLAGS := -L$(topdir)/libcap
CGO_LDFLAGS_ALLOW := -Wl,-?-wrap[=,][^-.@][^,]*
CGO_REQUIRED=$(shell $(topdir)/go/cgo-required.sh)
-ifeq ($(CGO_REQUIRED),0)
-# Hopefully this will not be needed at some point.
-GOBUILDTAG=-tags allthreadssyscall
-endif
endif
endif
diff --git a/cap/cap.go b/cap/cap.go
index 76f74df..107a345 100644
--- a/cap/cap.go
+++ b/cap/cap.go
@@ -42,14 +42,11 @@
// uniformly over the whole Go (and CGo linked) process runtime.
//
// Note, if the Go runtime syscall interface contains the Linux
-// variant syscall.AllThreadsSyscall() API (it is not in go1.15
-// for example, but see https://github.com/golang/go/issues/1435 for
-// current status) then this present package can use that to invoke
-// Capability setting system calls in pure Go binaries. In such an
-// enhanced Go runtime, to force this behavior, use the CGO_ENABLED=0
-// environment variable and, for now, a build tag:
-//
-// CGO_ENABLED=0 go build -tags allthreadssyscall ...
+// variant syscall.AllThreadsSyscall() API (it debuted in go1.16 see
+// https://github.com/golang/go/issues/1435 for actual status) then
+// the "psx" package will use that to invoke Capability setting system
+// calls in pure Go binaries. In such an enhanced Go runtime, to force
+// this behavior, use the CGO_ENABLED=0 environment variable.
//
//
// Copyright (c) 2019,20 Andrew G. Morgan <morgan@kernel.org>
diff --git a/go/Makefile b/go/Makefile
index 05ec7bf..b8745f1 100644
--- a/go/Makefile
+++ b/go/Makefile
@@ -54,7 +54,7 @@ compare-cap: compare-cap.go $(CAPGOPACKAGE)
GO111MODULE=off CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" GOPATH=$(GOPATH) $(GO) build $<
web: ../goapps/web/web.go $(CAPGOPACKAGE)
- GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build -o $@ $(GOBUILDTAG) $<
+ GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build -o $@ $<
ifeq ($(RAISE_GO_FILECAP),yes)
make -C ../progs setcap
sudo ../progs/setcap cap_setpcap,cap_net_bind_service=p web
@@ -62,16 +62,16 @@ ifeq ($(RAISE_GO_FILECAP),yes)
endif
setid: ../goapps/setid/setid.go $(CAPGOPACKAGE) $(PSXGOPACKAGE)
- GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build -o $@ $(GOBUILDTAG) $<
+ GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build -o $@ $<
gowns: ../goapps/gowns/gowns.go $(CAPGOPACKAGE)
- GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build -o $@ $(GOBUILDTAG) $<
+ GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build -o $@ $<
ok: ok.go
GO111MODULE=off CGO_ENABLED=0 GOPATH=$(GOPATH) $(GO) build $<
try-launching: try-launching.go $(CAPGOPACKAGE) ok
- GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build $(GOBUILDTAG) $<
+ GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build $<
ifeq ($(CGO_REQUIRED),0)
GO111MODULE=off CGO_ENABLED="1" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build -o $@-cgo $<
endif
diff --git a/psx/psx.go b/psx/psx.go
index 77858ad..b1b530a 100644
--- a/psx/psx.go
+++ b/psx/psx.go
@@ -1,5 +1,5 @@
// +build linux,!cgo
-// +build go1.16 allthreadssyscall
+// +build go1.16
package psx // import "kernel.org/pub/linux/libs/security/libcap/psx"
--
2.29.2

View File

@ -0,0 +1,54 @@
From 676ced165d907d58af903fba0a434ff69087bba6 Mon Sep 17 00:00:00 2001
From: "Andrew G. Morgan" <morgan@kernel.org>
Date: Wed, 23 Dec 2020 08:25:52 -0800
Subject: [PATCH 3/7] Minor fixes for "cap" package documentation.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
---
cap/launch.go | 8 ++++----
cap/text.go | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/cap/launch.go b/cap/launch.go
index 2f37a2a..4ae449c 100644
--- a/cap/launch.go
+++ b/cap/launch.go
@@ -106,18 +106,18 @@ var ErrLaunchFailed = errors.New("launch failed")
var ErrNoLaunch = errors.New("launch not supported")
// ErrAmbiguousChroot indicates that the Launcher is being used in
-// addition to callback supplied Chroot. The former should be used
+// addition to a callback supplied Chroot. The former should be used
// exclusively for this.
var ErrAmbiguousChroot = errors.New("use Launcher for chroot")
// ErrAmbiguousIDs indicates that the Launcher is being used in
-// addition to callback supplied Credentials. The former should be
+// addition to a callback supplied Credentials. The former should be
// used exclusively for this.
var ErrAmbiguousIDs = errors.New("use Launcher for uids and gids")
// ErrAmbiguousAmbient indicates that the Launcher is being used in
-// addition callback supplied ambient set and the former should be
-// used exclusively in a Launch call.
+// addition to a callback supplied ambient set and the former should
+// be used exclusively in a Launch call.
var ErrAmbiguousAmbient = errors.New("use Launcher for ambient caps")
// lName is the name we temporarily give to the launcher thread. Note,
diff --git a/cap/text.go b/cap/text.go
index 11dae90..cf11a2d 100644
--- a/cap/text.go
+++ b/cap/text.go
@@ -187,7 +187,7 @@ var ErrBadText = errors.New("bad text")
//
// "=p all+ei" "all=pie" "=pi all+e" "=eip"
//
-// "cap_chown=p cap_setuid=i" "cap_chown=ip-p" "cap_chown=i"
+// "cap_setuid=p cap_chown=i" "cap_chown=ip-p" "cap_chown=i"
//
// "cap_chown=-p" "all=" "cap_setuid=pie-pie" "="
//
--
2.29.2

106
0004-checkpoint.patch Normal file
View File

@ -0,0 +1,106 @@
From 0799b36a415c081c35a6e8e0f2a6b739d574fbd5 Mon Sep 17 00:00:00 2001
From: "Andrew G. Morgan" <morgan@kernel.org>
Date: Tue, 15 Dec 2020 22:09:39 -0800
Subject: [PATCH 4/7] checkpoint
---
progs/capsh.c | 8 +++++---
progs/getcap.c | 10 ++++++----
progs/getpcaps.c | 7 ++++---
3 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/progs/capsh.c b/progs/capsh.c
index 899f79c..5ea340b 100644
--- a/progs/capsh.c
+++ b/progs/capsh.c
@@ -912,7 +912,7 @@ int main(int argc, char *argv[], char *envp[])
} else {
usage:
printf("usage: %s [args ...]\n"
- " --help this message (or try 'man capsh')\n"
+ " --help, -h this message (or try 'man capsh')\n"
" --print display capability relevant state\n"
" --decode=xxx decode a hex string to a list of caps\n"
" --supports=xxx exit 1 if capability xxx unsupported\n"
@@ -948,8 +948,10 @@ int main(int argc, char *argv[], char *envp[])
" -- remaining arguments are for " SHELL "\n"
" (without -- [%s] will simply exit(0))\n",
argv[0], argv[0]);
-
- exit(strcmp("--help", argv[i]) != 0);
+ if (strcmp("--help", argv[1]) && strcmp("-h", argv[1])) {
+ exit(1);
+ }
+ exit(0);
}
}
diff --git a/progs/getcap.c b/progs/getcap.c
index 225207f..b4a9a60 100644
--- a/progs/getcap.c
+++ b/progs/getcap.c
@@ -23,14 +23,14 @@ static int verbose = 0;
static int recursive = 0;
static int namespace = 0;
-static void usage(void)
+static void usage(int ok)
{
fprintf(stderr,
"usage: getcap [-v] [-r] [-h] [-n] <filename> [<filename> ...]\n"
"\n"
"\tdisplays the capabilities on the queried file(s).\n"
);
- exit(1);
+ exit(!ok);
}
static int do_getcap(const char *fname, const struct stat *stbuf,
@@ -93,13 +93,15 @@ int main(int argc, char **argv)
case 'n':
namespace = 1;
break;
+ case 'h':
+ usage(1);
default:
- usage();
+ usage(0);
}
}
if (!argv[optind])
- usage();
+ usage(0);
for (i=optind; argv[i] != NULL; i++) {
struct stat stbuf;
diff --git a/progs/getpcaps.c b/progs/getpcaps.c
index 497abcd..5cd81af 100644
--- a/progs/getpcaps.c
+++ b/progs/getpcaps.c
@@ -18,10 +18,10 @@ static void usage(int exiter)
" This program displays the capabilities on the queried process(es).\n"
" The capabilities are displayed in the cap_from_text(3) format.\n\n"
" Optional arguments:\n"
-" --help or --usage display this message.\n"
+" --help, -h or --usage display this message.\n"
" --verbose use a more verbose output format.\n"
" --ugly or --legacy use the archaic legacy output format.\n\n"
-"[Copyright (c) 1997-8,2007,2019 Andrew G. Morgan <morgan@kernel.org>]\n"
+"[Copyright (c) 1997-8,2007,2019 Andrew G. Morgan <morgan@kernel.org>]\n"
);
exit(exiter);
}
@@ -40,7 +40,8 @@ int main(int argc, char **argv)
int pid;
cap_t cap_d;
- if (!strcmp(argv[0], "--help") || !strcmp(argv[0], "--usage")) {
+ if (!strcmp(argv[0], "--help") || !strcmp(argv[0], "--usage") ||
+ !strcmp(argv[0], "-h")) {
usage(0);
} else if (!strcmp(argv[0], "--verbose")) {
verbose = 1;
--
2.29.2

View File

@ -0,0 +1,52 @@
From bdb10e77579c0a7d8a2d952a2cd938f50b02c9d0 Mon Sep 17 00:00:00 2001
From: "Andrew G. Morgan" <morgan@kernel.org>
Date: Sat, 26 Dec 2020 16:59:21 -0800
Subject: [PATCH 5/7] Clean up the exit status to match other binaries.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
---
progs/getcap.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/progs/getcap.c b/progs/getcap.c
index b4a9a60..e578bbd 100644
--- a/progs/getcap.c
+++ b/progs/getcap.c
@@ -23,14 +23,14 @@ static int verbose = 0;
static int recursive = 0;
static int namespace = 0;
-static void usage(int ok)
+static void usage(int code)
{
fprintf(stderr,
"usage: getcap [-v] [-r] [-h] [-n] <filename> [<filename> ...]\n"
"\n"
"\tdisplays the capabilities on the queried file(s).\n"
);
- exit(!ok);
+ exit(code);
}
static int do_getcap(const char *fname, const struct stat *stbuf,
@@ -94,14 +94,14 @@ int main(int argc, char **argv)
namespace = 1;
break;
case 'h':
- usage(1);
- default:
usage(0);
+ default:
+ usage(1);
}
}
if (!argv[optind])
- usage(0);
+ usage(1);
for (i=optind; argv[i] != NULL; i++) {
struct stat stbuf;
--
2.29.2

View File

@ -0,0 +1,235 @@
From 0f0c1fe489ec0ca69891a7999f5bda1c91e02f92 Mon Sep 17 00:00:00 2001
From: "Andrew G. Morgan" <morgan@kernel.org>
Date: Sat, 26 Dec 2020 17:35:40 -0800
Subject: [PATCH 6/7] People keep emailing me about the license for libcap.
There seems to have been a misconception that the tools and library
are GPL only. This has never been the case. The system was developed
from the start with a you-choose license: GPL(2 at the time) OR
BSD 3-clause. When GPL3 was released, it was decided that the
distribution would not follow that. As such, everything is:
BSD 3-clause or GPL2 (you choose).
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
---
progs/capsh.c | 58 ++++++++++++++++++++++++++----------------------
progs/getcap.c | 15 ++++++++-----
progs/getpcaps.c | 23 +++++++++++--------
progs/setcap.c | 10 ++++++++-
4 files changed, 65 insertions(+), 41 deletions(-)
diff --git a/progs/capsh.c b/progs/capsh.c
index 5ea340b..dfe420f 100644
--- a/progs/capsh.c
+++ b/progs/capsh.c
@@ -1,9 +1,10 @@
/*
* Copyright (c) 2008-11,16,19,2020 Andrew G. Morgan <morgan@kernel.org>
*
- * This is a simple 'bash' (-DSHELL) wrapper program that can be used
- * to raise and lower both the bset and pI capabilities before
- * invoking /bin/bash.
+ * This is a multifunction shell wrapper tool that can be used to
+ * launch capable files in various ways with a variety of settings. It
+ * also supports some testing modes, which are used extensively as
+ * part of the libcap build system.
*
* The --print option can be used as a quick test whether various
* capability manipulations work as expected (or not).
@@ -909,41 +910,46 @@ int main(int argc, char *argv[], char *envp[])
exit(1);
}
cap_free(iab);
+ } else if (!strcmp("--license", argv[i])) {
+ printf(
+ "%s has a you choose license: BSD 3-clause or GPL2\n"
+ "Copyright (c) 2008-11,16,19,2020 Andrew G. Morgan"
+ " <morgan@kernel.org>\n", argv[0]);
+ exit(0);
} else {
usage:
printf("usage: %s [args ...]\n"
- " --help, -h this message (or try 'man capsh')\n"
- " --print display capability relevant state\n"
- " --decode=xxx decode a hex string to a list of caps\n"
- " --supports=xxx exit 1 if capability xxx unsupported\n"
- " --has-p=xxx exit 1 if capability xxx not permitted\n"
- " --has-i=xxx exit 1 if capability xxx not inheritable\n"
- " --drop=xxx remove xxx,.. capabilities from bset\n"
- " --dropped=xxx exit 1 unless bounding cap xxx dropped\n"
- " --has-ambient exit 1 unless ambient vector supported\n"
" --has-a=xxx exit 1 if capability xxx not ambient\n"
+ " --has-ambient exit 1 unless ambient vector supported\n"
" --addamb=xxx add xxx,... capabilities to ambient set\n"
- " --delamb=xxx remove xxx,... capabilities from ambient\n"
- " --noamb reset (drop) all ambient capabilities\n"
+ " --cap-uid=<n> use libcap cap_setuid() to change uid\n"
" --caps=xxx set caps as per cap_from_text()\n"
- " --inh=xxx set xxx,.. inheritable set\n"
- " --secbits=<n> write a new value for securebits\n"
+ " --chroot=path chroot(2) to this path\n"
+ " --decode=xxx decode a hex string to a list of caps\n"
+ " --delamb=xxx remove xxx,... capabilities from ambient\n"
+ " --forkfor=<n> fork and make child sleep for <n> sec\n"
+ " --gid=<n> set gid to <n> (hint: id <username>)\n"
+ " --groups=g,... set the supplemental groups\n"
+ " --has-p=xxx exit 1 if capability xxx not permitted\n"
+ " --has-i=xxx exit 1 if capability xxx not inheritable\n"
+ " --help, -h this message (or try 'man capsh')\n"
" --iab=... use cap_iab_from_text() to set iab\n"
- " --keep=<n> set keep-capability bit to <n>\n"
- " --uid=<n> set uid to <n> (hint: id <username>)\n"
- " --cap-uid=<n> libcap cap_setuid() to change uid\n"
+ " --inh=xxx set xxx,.. inheritable set\n"
+ " --inmode=<xxx> exit 1 if current mode is not <xxx>\n"
" --is-uid=<n> exit 1 if uid != <n>\n"
- " --gid=<n> set gid to <n> (hint: id <username>)\n"
" --is-gid=<n> exit 1 if gid != <n>\n"
- " --groups=g,... set the supplemental groups\n"
- " --user=<name> set uid,gid and groups to that of user\n"
- " --chroot=path chroot(2) to this path\n"
+ " --keep=<n> set keep-capability bit to <n>\n"
+ " --killit=<n> send signal(n) to child\n"
+ " --license display license info\n"
" --modes list libcap named capability modes\n"
" --mode=<xxx> set capability mode to <xxx>\n"
- " --inmode=<xxx> exit 1 if current mode is not <xxx>\n"
- " --killit=<n> send signal(n) to child\n"
- " --forkfor=<n> fork and make child sleep for <n> sec\n"
+ " --noamb reset (drop) all ambient capabilities\n"
+ " --print display capability relevant state\n"
+ " --secbits=<n> write a new value for securebits\n"
" --shell=/xx/yy use /xx/yy instead of " SHELL " for --\n"
+ " --supports=xxx exit 1 if capability xxx unsupported\n"
+ " --uid=<n> set uid to <n> (hint: id <username>)\n"
+ " --user=<name> set uid,gid and groups to that of user\n"
" == re-exec(capsh) with args as for --\n"
" -- remaining arguments are for " SHELL "\n"
" (without -- [%s] will simply exit(0))\n",
diff --git a/progs/getcap.c b/progs/getcap.c
index e578bbd..208bd6a 100644
--- a/progs/getcap.c
+++ b/progs/getcap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997,2007 Andrew G. Morgan <morgan@kernel.org>
+ * Copyright (c) 1997,2007 Andrew G. Morgan <morgan@kernel.org>
*
* This displays the capabilities of a given file.
*/
@@ -26,9 +26,9 @@ static int namespace = 0;
static void usage(int code)
{
fprintf(stderr,
- "usage: getcap [-v] [-r] [-h] [-n] <filename> [<filename> ...]\n"
- "\n"
- "\tdisplays the capabilities on the queried file(s).\n"
+ "usage: getcap [-h] [-l] [-n] [-r] [-v] <filename> [<filename> ...]\n"
+ "\n"
+ "\tdisplays the capabilities on the queried file(s).\n"
);
exit(code);
}
@@ -82,7 +82,7 @@ int main(int argc, char **argv)
{
int i, c;
- while ((c = getopt(argc, argv, "rvhn")) > 0) {
+ while ((c = getopt(argc, argv, "rvhnl")) > 0) {
switch(c) {
case 'r':
recursive = 1;
@@ -95,6 +95,11 @@ int main(int argc, char **argv)
break;
case 'h':
usage(0);
+ case 'l':
+ printf("%s has a you choose license: BSD 3-clause or GPL2\n"
+ "Copyright (c) 1997,2007 Andrew G. Morgan"
+ " <morgan@kernel.org>\n", argv[0]);
+ exit(0);
default:
usage(1);
}
diff --git a/progs/getpcaps.c b/progs/getpcaps.c
index 5cd81af..5bc511e 100644
--- a/progs/getpcaps.c
+++ b/progs/getpcaps.c
@@ -11,19 +11,19 @@
#include <stdlib.h>
#include <sys/capability.h>
-static void usage(int exiter)
+static void usage(int code)
{
fprintf(stderr,
"usage: getcaps <pid> [<pid> ...]\n\n"
" This program displays the capabilities on the queried process(es).\n"
-" The capabilities are displayed in the cap_from_text(3) format.\n\n"
-" Optional arguments:\n"
-" --help, -h or --usage display this message.\n"
-" --verbose use a more verbose output format.\n"
-" --ugly or --legacy use the archaic legacy output format.\n\n"
-"[Copyright (c) 1997-8,2007,2019 Andrew G. Morgan <morgan@kernel.org>]\n"
- );
- exit(exiter);
+ " The capabilities are displayed in the cap_from_text(3) format.\n"
+ "\n"
+ " Optional arguments:\n"
+ " --help, -h or --usage display this message.\n"
+ " --verbose use a more verbose output format.\n"
+ " --ugly or --legacy use the archaic legacy output format.\n"
+ " --license display license info\n");
+ exit(code);
}
int main(int argc, char **argv)
@@ -43,6 +43,11 @@ int main(int argc, char **argv)
if (!strcmp(argv[0], "--help") || !strcmp(argv[0], "--usage") ||
!strcmp(argv[0], "-h")) {
usage(0);
+ } else if (!strcmp(argv[0], "--license")) {
+ printf("%s has a you choose license: BSD 3-clause or GPL2\n"
+"[Copyright (c) 1997-8,2007,2019 Andrew G. Morgan <morgan@kernel.org>]\n",
+ argv[0]);
+ exit(0);
} else if (!strcmp(argv[0], "--verbose")) {
verbose = 1;
continue;
diff --git a/progs/setcap.c b/progs/setcap.c
index f675cdd..930429a 100644
--- a/progs/setcap.c
+++ b/progs/setcap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997,2007-8 Andrew G. Morgan <morgan@kernel.org>
+ * Copyright (c) 1997,2007-8,2020 Andrew G. Morgan <morgan@kernel.org>
*
* This sets/verifies the capabilities of a given file.
*/
@@ -26,6 +26,7 @@ static void usage(int status)
" -q quietly\n"
" -v validate supplied capability matches file\n"
" -n <rootid> write a user namespace limited capability\n"
+ " --license display the license info\n"
);
exit(status);
}
@@ -91,6 +92,13 @@ int main(int argc, char **argv)
quiet = 1;
continue;
}
+ if (!strcmp("--license", *argv)) {
+ printf(
+ "%s has a you choose license: BSD 3-clause or GPL2\n"
+ "Copyright (c) 1997,2007-8,2020 Andrew G. Morgan"
+ " <morgan@kernel.org>\n", argv[0]);
+ exit(0);
+ }
if (!strcmp(*argv, "-h")) {
usage(0);
}
--
2.29.2

View File

@ -0,0 +1,188 @@
From f552b8f7403bf535832e703641e8fcee6adf6630 Mon Sep 17 00:00:00 2001
From: "Andrew G. Morgan" <morgan@kernel.org>
Date: Sat, 26 Dec 2020 21:42:15 -0800
Subject: [PATCH 7/7] Augment NOPRIV libcap mode with the sticky NO_NEW_PRIVS
prctl bit.
Since I last visited securebits no privs mode, a new prctl bit
has been added (it isn't a securebit, but a parallel implementation
of something similar). So, layer that bit on top of NOPRIV mode.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
---
cap/convenience.go | 4 ++++
go/try-launching.go | 10 ++++++++++
libcap/cap_proc.c | 14 +++++++++++++-
progs/capsh.c | 17 +++++++++++++++--
tests/libcap_launch_test.c | 3 ++-
5 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/cap/convenience.go b/cap/convenience.go
index f094e52..9580903 100644
--- a/cap/convenience.go
+++ b/cap/convenience.go
@@ -36,6 +36,7 @@ const (
prSetKeepCaps = 8
prGetSecureBits = 27
prSetSecureBits = 28
+ prSetNoNewPrivs = 38
)
// GetSecbits returns the current setting of the process' Secbits.
@@ -163,6 +164,9 @@ func (sc *syscaller) setMode(m Mode) error {
}
w.ClearFlag(Permitted)
+ // For good measure.
+ sc.prctlwcall6(prSetNoNewPrivs, 1, 0, 0, 0, 0)
+
return nil
}
diff --git a/go/try-launching.go b/go/try-launching.go
index 272fd0a..9f20e6b 100644
--- a/go/try-launching.go
+++ b/go/try-launching.go
@@ -28,6 +28,7 @@ func tryLaunching() {
iab string
uid int
gid int
+ mode cap.Mode
groups []int
}{
{args: []string{root + "/go/ok"}},
@@ -44,6 +45,11 @@ func tryLaunching() {
chroot: root + "/go",
fail: syscall.Getuid() != 0,
},
+ {
+ args: []string{root + "/progs/tcapsh-static", "--inmode=NOPRIV", "--has-no-new-privs"},
+ mode: cap.ModeNoPriv,
+ fail: syscall.Getuid() != 0,
+ },
}
ps := make([]int, len(vs))
@@ -61,6 +67,9 @@ func tryLaunching() {
if v.gid != 0 {
e.SetGroups(v.gid, v.groups)
}
+ if v.mode != 0 {
+ e.SetMode(v.mode)
+ }
if v.iab != "" {
if iab, err := cap.IABFromText(v.iab); err != nil {
log.Fatalf("failed to parse iab=%q: %v", v.iab, err)
@@ -68,6 +77,7 @@ func tryLaunching() {
e.SetIAB(iab)
}
}
+ log.Printf("[%d] trying: %q\n", i, v.args)
if ps[i], err = e.Launch(nil); err != nil {
if v.fail {
continue
diff --git a/libcap/cap_proc.c b/libcap/cap_proc.c
index 3929f66..1329f94 100644
--- a/libcap/cap_proc.c
+++ b/libcap/cap_proc.c
@@ -390,13 +390,21 @@ static int _cap_set_secbits(struct syscaller_s *sc, unsigned bits)
}
/*
- * Set the security mode of the current process.
+ * Set the secbits of the current process.
*/
int cap_set_secbits(unsigned bits)
{
return _cap_set_secbits(&multithread, bits);
}
+/*
+ * Attempt to raise the no new privs prctl value.
+ */
+static void _cap_set_no_new_privs(struct syscaller_s *sc)
+{
+ (void) _libcap_wprctl6(sc, PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0, 0);
+}
+
/*
* Some predefined constants
*/
@@ -448,7 +456,11 @@ static int _cap_set_mode(struct syscaller_s *sc, cap_mode_t flavor)
(void) _cap_drop_bound(sc, c);
}
(void) cap_clear_flag(working, CAP_PERMITTED);
+
+ /* for good measure */
+ _cap_set_no_new_privs(sc);
break;
+
default:
errno = EINVAL;
ret = -1;
diff --git a/progs/capsh.c b/progs/capsh.c
index dfe420f..a39ceeb 100644
--- a/progs/capsh.c
+++ b/progs/capsh.c
@@ -108,8 +108,9 @@ static void arg_print(void)
set = cap_get_secbits();
if (set >= 0) {
const char *b = binary(set); /* verilog convention for binary string */
- printf("Securebits: 0%lo/0x%lx/%u'b%s\n", set, set,
- (unsigned) strlen(b), b);
+ printf("Securebits: 0%lo/0x%lx/%u'b%s (no-new-privs=%d)\n", set, set,
+ (unsigned) strlen(b), b,
+ prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0, 0));
printf(" secure-noroot: %s (%s)\n",
(set & SECBIT_NOROOT) ? "yes":"no",
(set & SECBIT_NOROOT_LOCKED) ? "locked":"unlocked");
@@ -910,6 +911,16 @@ int main(int argc, char *argv[], char *envp[])
exit(1);
}
cap_free(iab);
+ } else if (!strcmp("--no-new-privs", argv[i])) {
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0, 0) != 0) {
+ perror("unable to set no-new-privs");
+ exit(1);
+ }
+ } else if (!strcmp("--has-no-new-privs", argv[i])) {
+ if (prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0, 0) != 1) {
+ fprintf(stderr, "no-new-privs not set\n");
+ exit(1);
+ }
} else if (!strcmp("--license", argv[i])) {
printf(
"%s has a you choose license: BSD 3-clause or GPL2\n"
@@ -932,6 +943,7 @@ int main(int argc, char *argv[], char *envp[])
" --groups=g,... set the supplemental groups\n"
" --has-p=xxx exit 1 if capability xxx not permitted\n"
" --has-i=xxx exit 1 if capability xxx not inheritable\n"
+ " --has-no-new-privs exit 1 if privs not limited\n"
" --help, -h this message (or try 'man capsh')\n"
" --iab=... use cap_iab_from_text() to set iab\n"
" --inh=xxx set xxx,.. inheritable set\n"
@@ -943,6 +955,7 @@ int main(int argc, char *argv[], char *envp[])
" --license display license info\n"
" --modes list libcap named capability modes\n"
" --mode=<xxx> set capability mode to <xxx>\n"
+ " --no-new-privs set sticky process privilege limiter\n"
" --noamb reset (drop) all ambient capabilities\n"
" --print display capability relevant state\n"
" --secbits=<n> write a new value for securebits\n"
diff --git a/tests/libcap_launch_test.c b/tests/libcap_launch_test.c
index c9ef205..bba38c6 100644
--- a/tests/libcap_launch_test.c
+++ b/tests/libcap_launch_test.c
@@ -70,7 +70,8 @@ int main(int argc, char **argv) {
.iab = "!^cap_chown"
},
{
- .args = { "../progs/tcapsh-static", "--inmode=NOPRIV" },
+ .args = { "../progs/tcapsh-static", "--inmode=NOPRIV",
+ "--has-no-new-privs" },
.result = 0,
.mode = CAP_MODE_NOPRIV
},
--
2.29.2

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Mon Jan 4 19:30:44 UTC 2021 - Dirk Müller <dmueller@suse.com>
- add 0001-Improve-the-usage-and-diagnostic-message-for-setcap.patch
0002-No-longer-need-the-Go-build-tag-allthreadssyscall.patch
0003-Minor-fixes-for-cap-package-documentation.patch
0004-checkpoint.patch
0005-Clean-up-the-exit-status-to-match-other-binaries.patch
0006-People-keep-emailing-me-about-the-license-for-libcap.patch
0007-Augment-NOPRIV-libcap-mode-with-the-sticky-NO_NEW_PR.patch
-------------------------------------------------------------------
Mon Jan 4 08:46:44 UTC 2021 - Dirk Müller <dmueller@suse.com>

View File

@ -25,6 +25,13 @@ Group: Development/Libraries/C and C++
URL: https://sites.google.com/site/fullycapable/
Source: https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-%{version}.tar.xz
Source2: baselibs.conf
Patch0: 0001-Improve-the-usage-and-diagnostic-message-for-setcap.patch
Patch1: 0002-No-longer-need-the-Go-build-tag-allthreadssyscall.patch
Patch2: 0003-Minor-fixes-for-cap-package-documentation.patch
Patch3: 0004-checkpoint.patch
Patch4: 0005-Clean-up-the-exit-status-to-match-other-binaries.patch
Patch5: 0006-People-keep-emailing-me-about-the-license-for-libcap.patch
Patch6: 0007-Augment-NOPRIV-libcap-mode-with-the-sticky-NO_NEW_PR.patch
BuildRequires: fdupes
BuildRequires: glibc-devel-static
BuildRequires: pkgconfig
@ -89,6 +96,7 @@ libcap.
%prep
%setup -q
%autopatch -p1
%build
%global _lto_cflags %{_lto_cflags} -ffat-lto-objects