aboutsummaryrefslogtreecommitdiff
path: root/progs
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2016-02-06 19:49:07 -0800
committerAndrew G. Morgan <morgan@kernel.org>2016-02-06 19:49:07 -0800
commit0f0eca489e979b4a8526e521f962455e474a27a0 (patch)
tree0e8027ecad22b844deb36f5bee73712f5cc57b77 /progs
parentdce069b617cf5e42fde707196eaf2ee8d62bc96c (diff)
downloadlibcap-0f0eca489e979b4a8526e521f962455e474a27a0.tar.gz
Add initial support for the ambient set.
The ambient set is some strangeness associated with trying to revive naive inheritance. While personally not a fan of this feature, I recognize it is in the kernel so libcap now supports it with three new functions: int cap_get_ambient(cap_value_t cap) int cap_set_ambient(cap_value_t cap, cap_flag_value_t set) int cap_reset_ambient(void) Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
Diffstat (limited to 'progs')
-rw-r--r--progs/capsh.c174
1 files changed, 99 insertions, 75 deletions
diff --git a/progs/capsh.c b/progs/capsh.c
index 3ceadcd..9c907a7 100644
--- a/progs/capsh.c
+++ b/progs/capsh.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-11 Andrew G. Morgan <morgan@kernel.org>
+ * Copyright (c) 2008-11,16 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
@@ -43,6 +43,103 @@ static char *binary(unsigned long value)
return string + i;
}
+static void display_prctl_set(const char *name, int (*fn)(cap_value_t))
+{
+ unsigned cap;
+ const char *sep;
+ int set;
+
+ printf("%s set =", name);
+ for (sep = "", cap=0; (set = fn(cap)) >= 0; cap++) {
+ char *ptr;
+ if (!set) {
+ continue;
+ }
+
+ ptr = cap_to_name(cap);
+ if (ptr == NULL) {
+ printf("%s%u", sep, cap);
+ } else {
+ printf("%s%s", sep, ptr);
+ cap_free(ptr);
+ }
+ sep = ",";
+ }
+ if (!cap) {
+ printf(" <unsupported>\n");
+ } else {
+ printf("\n");
+ }
+}
+
+/* arg_print displays the current capability state of the process */
+static void arg_print(void)
+{
+ int set, status, j;
+ cap_t all;
+ char *text;
+ const char *sep;
+ struct group *g;
+ gid_t groups[MAX_GROUPS], gid;
+ uid_t uid;
+ struct passwd *u;
+
+ all = cap_get_proc();
+ text = cap_to_text(all, NULL);
+ printf("Current: %s\n", text);
+ cap_free(text);
+ cap_free(all);
+
+ display_prctl_set("Bounding", cap_get_bound);
+ display_prctl_set("Ambient", cap_get_ambient);
+ set = prctl(PR_GET_SECUREBITS);
+ if (set >= 0) {
+ const char *b;
+ b = binary(set); /* use verilog convention for binary string */
+ printf("Securebits: 0%o/0x%x/%u'b%s\n", set, set,
+ (unsigned) strlen(b), b);
+ printf(" secure-noroot: %s (%s)\n",
+ (set & SECBIT_NOROOT) ? "yes":"no",
+ (set & SECBIT_NOROOT_LOCKED) ? "locked":"unlocked");
+ printf(" secure-no-suid-fixup: %s (%s)\n",
+ (set & SECBIT_NO_SETUID_FIXUP) ? "yes":"no",
+ (set & SECBIT_NO_SETUID_FIXUP_LOCKED) ? "locked":"unlocked");
+ printf(" secure-keep-caps: %s (%s)\n",
+ (set & SECBIT_KEEP_CAPS) ? "yes":"no",
+ (set & SECBIT_KEEP_CAPS_LOCKED) ? "locked":"unlocked");
+ if (CAP_AMBIENT_SUPPORTED()) {
+ printf(" secure-no-ambient-raise: %s (%s)\n",
+ (set & SECBIT_NO_CAP_AMBIENT_RAISE) ? "yes":"no",
+ (set & SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED) ?
+ "locked":"unlocked");
+ }
+ } else {
+ printf("[Securebits ABI not supported]\n");
+ set = prctl(PR_GET_KEEPCAPS);
+ if (set >= 0) {
+ printf(" prctl-keep-caps: %s (locking not supported)\n",
+ set ? "yes":"no");
+ } else {
+ printf("[Keepcaps ABI not supported]\n");
+ }
+ }
+ uid = getuid();
+ u = getpwuid(uid);
+ printf("uid=%u(%s)\n", getuid(), u ? u->pw_name : "???");
+ gid = getgid();
+ g = getgrgid(gid);
+ printf("gid=%u(%s)\n", gid, g ? g->gr_name : "???");
+ printf("groups=");
+ status = getgroups(MAX_GROUPS, groups);
+ sep = "";
+ for (j=0; j < status; j++) {
+ g = getgrgid(groups[j]);
+ printf("%s%u(%s)", sep, groups[j], g ? g->gr_name : "???");
+ sep = ",";
+ }
+ printf("\n");
+}
+
int main(int argc, char *argv[], char *envp[])
{
pid_t child;
@@ -482,80 +579,7 @@ int main(int argc, char *argv[], char *envp[])
exit(1);
}
} else if (!strcmp("--print", argv[i])) {
- unsigned cap;
- int set, status, j;
- cap_t all;
- char *text;
- const char *sep;
- struct group *g;
- gid_t groups[MAX_GROUPS], gid;
- uid_t uid;
- struct passwd *u;
-
- all = cap_get_proc();
- text = cap_to_text(all, NULL);
- printf("Current: %s\n", text);
- cap_free(text);
- cap_free(all);
-
- printf("Bounding set =");
- sep = "";
- for (cap=0; (set = cap_get_bound(cap)) >= 0; cap++) {
- char *ptr;
- if (!set) {
- continue;
- }
-
- ptr = cap_to_name(cap);
- if (ptr == NULL) {
- printf("%s%u", sep, cap);
- } else {
- printf("%s%s", sep, ptr);
- cap_free(ptr);
- }
- sep = ",";
- }
- printf("\n");
- set = prctl(PR_GET_SECUREBITS);
- if (set >= 0) {
- const char *b;
- b = binary(set); /* use verilog convention for binary string */
- printf("Securebits: 0%o/0x%x/%u'b%s\n", set, set,
- (unsigned) strlen(b), b);
- printf(" secure-noroot: %s (%s)\n",
- (set & 1) ? "yes":"no",
- (set & 2) ? "locked":"unlocked");
- printf(" secure-no-suid-fixup: %s (%s)\n",
- (set & 4) ? "yes":"no",
- (set & 8) ? "locked":"unlocked");
- printf(" secure-keep-caps: %s (%s)\n",
- (set & 16) ? "yes":"no",
- (set & 32) ? "locked":"unlocked");
- } else {
- printf("[Securebits ABI not supported]\n");
- set = prctl(PR_GET_KEEPCAPS);
- if (set >= 0) {
- printf(" prctl-keep-caps: %s (locking not supported)\n",
- set ? "yes":"no");
- } else {
- printf("[Keepcaps ABI not supported]\n");
- }
- }
- uid = getuid();
- u = getpwuid(uid);
- printf("uid=%u(%s)\n", getuid(), u ? u->pw_name : "???");
- gid = getgid();
- g = getgrgid(gid);
- printf("gid=%u(%s)\n", gid, g ? g->gr_name : "???");
- printf("groups=");
- status = getgroups(MAX_GROUPS, groups);
- sep = "";
- for (j=0; j < status; j++) {
- g = getgrgid(groups[j]);
- printf("%s%u(%s)", sep, groups[j], g ? g->gr_name : "???");
- sep = ",";
- }
- printf("\n");
+ arg_print();
} else if ((!strcmp("--", argv[i])) || (!strcmp("==", argv[i]))) {
argv[i] = strdup(argv[i][0] == '-' ? "/bin/bash" : argv[0]);
argv[argc] = NULL;