From b138da4a4b9d57b850ca4d0061969f5e3299861d Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Sat, 3 Nov 2012 20:31:18 -0700 Subject: Imported Upstream version 2.22 --- libcap/cap_alloc.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 libcap/cap_alloc.c (limited to 'libcap/cap_alloc.c') diff --git a/libcap/cap_alloc.c b/libcap/cap_alloc.c new file mode 100644 index 0000000..5fa5e93 --- /dev/null +++ b/libcap/cap_alloc.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 1997-8 Andrew G Morgan + * + * This file deals with allocation and deallocation of internal + * capability sets as specified by POSIX.1e (formerlly, POSIX 6). + */ + +#include "libcap.h" + +/* + * Obtain a blank set of capabilities + */ + +cap_t cap_init(void) +{ + __u32 *raw_data; + cap_t result; + + raw_data = malloc( sizeof(__u32) + sizeof(*result) ); + + if (raw_data == NULL) { + _cap_debug("out of memory"); + errno = ENOMEM; + return NULL; + } + + *raw_data = CAP_T_MAGIC; + result = (cap_t) (raw_data + 1); + memset(result, 0, sizeof(*result)); + + result->head.version = _LIBCAP_CAPABILITY_VERSION; + capget(&result->head, NULL); /* load the kernel-capability version */ + + switch (result->head.version) { +#ifdef _LINUX_CAPABILITY_VERSION_1 + case _LINUX_CAPABILITY_VERSION_1: + break; +#endif +#ifdef _LINUX_CAPABILITY_VERSION_2 + case _LINUX_CAPABILITY_VERSION_2: + break; +#endif +#ifdef _LINUX_CAPABILITY_VERSION_3 + case _LINUX_CAPABILITY_VERSION_3: + break; +#endif + default: /* No idea what to do */ + cap_free(result); + result = NULL; + break; + } + + return result; +} + +/* + * This is an internal library function to duplicate a string and + * tag the result as something cap_free can handle. + */ + +char *_libcap_strdup(const char *old) +{ + __u32 *raw_data; + + if (old == NULL) { + errno = EINVAL; + return NULL; + } + + raw_data = malloc( sizeof(__u32) + strlen(old) + 1 ); + if (raw_data == NULL) { + errno = ENOMEM; + return NULL; + } + + *(raw_data++) = CAP_S_MAGIC; + strcpy((char *) raw_data, old); + + return ((char *) raw_data); +} + +/* + * This function duplicates an internal capability set with + * malloc()'d memory. It is the responsibility of the user to call + * cap_free() to liberate it. + */ + +cap_t cap_dup(cap_t cap_d) +{ + cap_t result; + + if (!good_cap_t(cap_d)) { + _cap_debug("bad argument"); + errno = EINVAL; + return NULL; + } + + result = cap_init(); + if (result == NULL) { + _cap_debug("out of memory"); + return NULL; + } + + memcpy(result, cap_d, sizeof(*cap_d)); + + return result; +} + + +/* + * Scrub and then liberate an internal capability set. + */ + +int cap_free(void *data_p) +{ + if ( !data_p ) + return 0; + + if ( good_cap_t(data_p) ) { + data_p = -1 + (__u32 *) data_p; + memset(data_p, 0, sizeof(__u32) + sizeof(struct _cap_struct)); + free(data_p); + data_p = NULL; + return 0; + } + + if ( good_cap_string(data_p) ) { + int length = strlen(data_p) + sizeof(__u32); + data_p = -1 + (__u32 *) data_p; + memset(data_p, 0, length); + free(data_p); + data_p = NULL; + return 0; + } + + _cap_debug("don't recognize what we're supposed to liberate"); + errno = EINVAL; + return -1; +} -- cgit v1.2.3