diff options
author | Andrew G. Morgan <morgan@kernel.org> | 2008-07-08 06:59:01 -0700 |
---|---|---|
committer | Andrew G. Morgan <morgan@kernel.org> | 2008-07-08 06:59:01 -0700 |
commit | f6c0eee763c5bd695b94a3e4249d73d785d66659 (patch) | |
tree | cc2d0ddc88773f90325e68c43dda67fb245e6be6 | |
parent | 3463a1393551bff930d19e50417e6e57f1df7324 (diff) | |
download | libcap-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/Makefile | 3 | ||||
-rw-r--r-- | contrib/bug400591/Makefile | 3 | ||||
-rw-r--r-- | contrib/bug400591/bug.c | 9 | ||||
-rw-r--r-- | libcap/cap_extint.c | 2 | ||||
-rw-r--r-- | libcap/cap_flag.c | 28 | ||||
-rw-r--r-- | libcap/cap_proc.c | 21 | ||||
-rw-r--r-- | libcap/cap_text.c | 4 | ||||
-rw-r--r-- | libcap/include/sys/capability.h | 9 | ||||
-rw-r--r-- | libcap/libcap.h | 7 | ||||
-rw-r--r-- | progs/getpcaps.c | 24 |
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); } } |