Add testing features to capsh.
Capabilities in their various guises can be complicated. Add
some simple test flags to capsh so we can script more test
cases.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
diff --git a/doc/cap_get_proc.3 b/doc/cap_get_proc.3
index 712b3ff..80f7e21 100644
--- a/doc/cap_get_proc.3
+++ b/doc/cap_get_proc.3
@@ -117,6 +117,10 @@
.I effective
capability set must have a raised
.BR CAP_SETPCAP .
+Further, to raise a specific ambient capability the
+.IR inheritable " and " permitted
+sets of the current process must contain the specified capability, and
+raised ambient bits will only be retained as long as this remains true.
.PP
.BR cap_reset_ambient ()
resets all of the ambient capabilities for the current process to
diff --git a/doc/capsh.1 b/doc/capsh.1
index c3dc8fe..1e28b59 100644
--- a/doc/capsh.1
+++ b/doc/capsh.1
@@ -107,6 +107,10 @@
process. Following this command the prevailing effective capabilities
will be lowered.
.TP
+.BI --is-uid= <id>
+Exit with status 1 unless the current
+.IR uid " equals " <id> .
+.TP
.BI --gid= <id>
Force all
.B gid
@@ -116,6 +120,10 @@
.BR setgid (2)
system call.
.TP
+.BI --is-gid= <id>
+Exit with status 1 unless the current
+.IR gid " equals " <id> .
+.TP
.BI --groups= <gid-list>
Set the supplementary groups to the numerical list provided. The
groups are set with the
@@ -211,10 +219,24 @@
kernel 2.6.27. However, when run on kernel 2.6.38 it will silently
succeed.
.TP
+.BI --has-p= xxx
+Exit with status 1 unless the
+.I permitted
+vector has capability
+.B xxx
+raised.
+.TP
.B --has-ambient
Performs a check to see if the running kernel supports ambient
capabilities. If not, the capsh command exits with status 1.
.TP
+.BI --has-a= xxx
+Exit with status 1 unless the
+.I ambient
+vector has capability
+.B xxx
+raised.
+.TP
.BI --addamb= xxx
Adds the specificed ambient capability to the running process.
.TP
diff --git a/progs/capsh.c b/progs/capsh.c
index ac3d108..2875096 100644
--- a/progs/capsh.c
+++ b/progs/capsh.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-11,16,19 Andrew G. Morgan <morgan@kernel.org>
+ * Copyright (c) 2008-11,16,19,2020 Andrew G. Morgan <morgan@kernel.org>
*
* This is a simple 'bash' wrapper program that can be used to
* raise and lower both the bset and pI capabilities before invoking
@@ -761,6 +761,51 @@
execve(argv[i], argv+i, envp);
fprintf(stderr, "execve /bin/bash failed!\n");
exit(1);
+ } else if (!strncmp("--has-p=", argv[i], 8)) {
+ cap_value_t cap;
+ cap_flag_value_t enabled;
+ cap_t orig;
+
+ if (cap_from_name(argv[i]+8, &cap) < 0) {
+ fprintf(stderr, "cap[%s] not recognized by libarary\n",
+ argv[i] + 8);
+ exit(1);
+ }
+ orig = cap_get_proc();
+ if (cap_get_flag(orig, cap, CAP_PERMITTED, &enabled) || !enabled) {
+ fprintf(stderr, "cap[%s] not enabled\n", argv[i]+8);
+ exit(1);
+ }
+ cap_free(orig);
+ } else if (!strncmp("--has-a=", argv[i], 8)) {
+ cap_value_t cap;
+ if (cap_from_name(argv[i]+8, &cap) < 0) {
+ fprintf(stderr, "cap[%s] not recognized by libarary\n",
+ argv[i] + 8);
+ exit(1);
+ }
+ if (!cap_get_ambient(cap)) {
+ fprintf(stderr, "cap[%s] not in ambient vector\n", argv[i]+8);
+ exit(1);
+ }
+ } else if (!strncmp("--is-uid=", argv[i], 9)) {
+ unsigned value;
+ uid_t uid;
+ value = strtoul(argv[i]+9, NULL, 0);
+ uid = getuid();
+ if (uid != value) {
+ fprintf(stderr, "uid: got=%d, want=%d\n", uid, value);
+ exit(1);
+ }
+ } else if (!strncmp("--is-gid=", argv[i], 9)) {
+ unsigned value;
+ gid_t gid;
+ value = strtoul(argv[i]+9, NULL, 0);
+ gid = getgid();
+ if (gid != value) {
+ fprintf(stderr, "gid: got=%d, want=%d\n", gid, value);
+ exit(1);
+ }
} else {
usage:
printf("usage: %s [args ...]\n"
@@ -768,8 +813,10 @@
" --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"
" --drop=xxx remove xxx,.. capabilities from bset\n"
- " --has-ambient fail immediately unless ambient supported\n"
+ " --has-ambient exit 1 unless ambient vector supported\n"
+ " --has-a=xxx exit 1 if capability xxx not ambient\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"
@@ -779,7 +826,9 @@
" --keep=<n> set keep-capabability bit to <n>\n"
" --uid=<n> set uid to <n> (hint: id <username>)\n"
" --cap-uid=<n> libcap cap_setuid() to change uid\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"