aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2008-07-08 06:59:01 -0700
committerAndrew G. Morgan <morgan@kernel.org>2008-07-08 06:59:01 -0700
commitf6c0eee763c5bd695b94a3e4249d73d785d66659 (patch)
treecc2d0ddc88773f90325e68c43dda67fb245e6be6
parent3463a1393551bff930d19e50417e6e57f1df7324 (diff)
downloadlibcap-f6c0eee763c5bd695b94a3e4249d73d785d66659.tar.gz
Fix cap_copy_int(), add two functions cap_get_pid() and cap_compare()
Test new and old function with modified test. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--contrib/Makefile3
-rw-r--r--contrib/bug400591/Makefile3
-rw-r--r--contrib/bug400591/bug.c9
-rw-r--r--libcap/cap_extint.c2
-rw-r--r--libcap/cap_flag.c28
-rw-r--r--libcap/cap_proc.c21
-rw-r--r--libcap/cap_text.c4
-rw-r--r--libcap/include/sys/capability.h9
-rw-r--r--libcap/libcap.h7
-rw-r--r--progs/getpcaps.c24
10 files changed, 82 insertions, 28 deletions
diff --git a/contrib/Makefile b/contrib/Makefile
new file mode 100644
index 0000000..4749630
--- /dev/null
+++ b/contrib/Makefile
@@ -0,0 +1,3 @@
+.PHONY: all clean
+all clean:
+ for x in bug* ; do make -C $$x $@ || exit 1 ; done
diff --git a/contrib/bug400591/Makefile b/contrib/bug400591/Makefile
index f6e0ea3..320610c 100644
--- a/contrib/bug400591/Makefile
+++ b/contrib/bug400591/Makefile
@@ -2,7 +2,8 @@ all: bug
bug: bug.c ../../libcap Makefile
make -C ../../libcap
- cc --static -o $@ $< -L../../libcap -lcap
+ cc -g -I../../libcap/include --static -o $@ $< -L../../libcap -lcap
+ ./bug
clean:
rm -f bug.o bug
diff --git a/contrib/bug400591/bug.c b/contrib/bug400591/bug.c
index 363ca27..2ff2355 100644
--- a/contrib/bug400591/bug.c
+++ b/contrib/bug400591/bug.c
@@ -15,10 +15,7 @@ int main (int argc, char *argv[])
void *buffer;
char *text1, *text2;
- caps = cap_init();
- assert (caps);
-
- assert(capgetp(1, caps) == 0);
+ assert((caps = cap_get_pid(1)));
text1 = cap_to_text(caps, NULL);
assert(text1);
@@ -35,10 +32,12 @@ int main (int argc, char *argv[])
caps2 = cap_copy_int(buffer);
assert (caps2);
- text2 = cap_to_text(caps, NULL);
+ text2 = cap_to_text(caps2, NULL);
assert(text2);
assert(strcmp(text1, text2) == 0);
+ assert(cap_compare(caps, caps2) == 0);
+
return 0;
}
diff --git a/libcap/cap_extint.c b/libcap/cap_extint.c
index 4992360..5a0cc8e 100644
--- a/libcap/cap_extint.c
+++ b/libcap/cap_extint.c
@@ -98,7 +98,7 @@ 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) {
+ for (set=0; set<NUMBER_OF_CAP_SETS; ++set) {
int blk;
int bno = 0;
for (blk=0; blk<(CAP_SET_SIZE/sizeof(__u32)); ++blk) {
diff --git a/libcap/cap_flag.c b/libcap/cap_flag.c
index 78e83a5..52ec3b3 100644
--- a/libcap/cap_flag.c
+++ b/libcap/cap_flag.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-8 Andrew G. Morgan <morgan@kernel.org>
+ * Copyright (c) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
*
* This file deals with flipping of capabilities on internal
* capability sets as specified by POSIX.1e (formerlly, POSIX 6).
@@ -122,3 +122,29 @@ int cap_clear_flag(cap_t cap_d, cap_flag_t flag)
}
}
+/*
+ * 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/libcap/cap_proc.c b/libcap/cap_proc.c
index 61c5b12..7a6af39 100644
--- a/libcap/cap_proc.c
+++ b/libcap/cap_proc.c
@@ -62,6 +62,27 @@ int capgetp(pid_t pid, cap_t cap_d)
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)
diff --git a/libcap/cap_text.c b/libcap/cap_text.c
index e013714..fea3e17 100644
--- a/libcap/cap_text.c
+++ b/libcap/cap_text.c
@@ -23,10 +23,6 @@
/* Maximum output text length (16 per cap) */
#define CAP_TEXT_SIZE (16*__CAP_MAXBITS)
-#define LIBCAP_EFF 01
-#define LIBCAP_INH 02
-#define LIBCAP_PER 04
-
/*
* Parse a textual representation of capabilities, returning an internal
* representation.
diff --git a/libcap/include/sys/capability.h b/libcap/include/sys/capability.h
index ea19359..4b1f7a3 100644
--- a/libcap/include/sys/capability.h
+++ b/libcap/include/sys/capability.h
@@ -95,6 +95,7 @@ extern int cap_set_file(const char *, cap_t);
/* libcap/cap_proc.c */
extern cap_t cap_get_proc(void);
+extern cap_t cap_get_pid(pid_t);
extern int cap_set_proc(cap_t);
/* libcap/cap_extint.c */
@@ -108,9 +109,17 @@ 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);
+#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);
+
+/* 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/libcap/libcap.h b/libcap/libcap.h
index 4f64bd9..0c652ec 100644
--- a/libcap/libcap.h
+++ b/libcap/libcap.h
@@ -142,6 +142,13 @@ struct _cap_struct {
#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
diff --git a/progs/getpcaps.c b/progs/getpcaps.c
index 8d40264..e405a92 100644
--- a/progs/getpcaps.c
+++ b/progs/getpcaps.c
@@ -1,9 +1,7 @@
/*
- * $Id: getpcaps.c,v 1.2 1999/11/18 06:04:25 morgan Exp $
+ * Copyright (c) 1997,2008 Andrew G. Morgan <morgan@kernel.org>
*
- * Copyright (c) 1997 Andrew G. Morgan <morgan@kernel.org>
- *
- * This displays the capabilities of a given process.
+ * This displays the capabilities of given target process(es).
*/
#include <sys/types.h>
@@ -11,7 +9,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#undef _POSIX_SOURCE
#include <sys/capability.h>
static void usage(void)
@@ -28,28 +25,22 @@ static void usage(void)
int main(int argc, char **argv)
{
int retval = 0;
- cap_t cap_d;
if (argc < 2) {
usage();
}
- cap_d = cap_init();
for ( ++argv; --argc > 0; ++argv ) {
ssize_t length;
int pid;
-
- if (cap_d == NULL) {
- fprintf(stderr, "Failed to make a blank capability set\n"
- " (%s)\n", strerror(errno));
- exit(1);
- }
+ cap_t cap_d;
pid = atoi(argv[0]);
- /* this is a non-POSIX function */
- if (capgetp(pid, cap_d)) {
+
+ cap_d = cap_get_pid(pid);
+ if (cap_d == NULL) {
fprintf(stderr, "Failed to get cap's for proccess %d:"
- " (%s) - need new libcap?\n", pid, strerror(errno));
+ " (%s)\n", pid, strerror(errno));
retval = 1;
continue;
} else {
@@ -57,6 +48,7 @@ int main(int argc, char **argv)
fprintf(stderr, "Capabilities for `%s': %s\n", *argv, result);
cap_free(result);
result = NULL;
+ cap_free(cap_d);
}
}