aboutsummaryrefslogtreecommitdiff
path: root/libcap/cap_extint.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcap/cap_extint.c')
-rw-r--r--libcap/cap_extint.c72
1 files changed, 41 insertions, 31 deletions
diff --git a/libcap/cap_extint.c b/libcap/cap_extint.c
index bf0967b..462cc65 100644
--- a/libcap/cap_extint.c
+++ b/libcap/cap_extint.c
@@ -36,40 +36,49 @@ struct cap_ext_struct {
*/
static size_t _libcap_min_ext_flag_size = CAP_SET_SIZE < 8 ? CAP_SET_SIZE : 8;
+static ssize_t _cap_size_locked(cap_t cap_d)
+{
+ size_t j, used;
+ for (j=used=0; j<CAP_SET_SIZE; j+=sizeof(__u32)) {
+ int i;
+ __u32 val = 0;
+ for (i=0; i<NUMBER_OF_CAP_SETS; ++i) {
+ val |= cap_d->u[j/sizeof(__u32)].flat[i];
+ }
+ if (val == 0) {
+ continue;
+ }
+ if (val > 0x0000ffff) {
+ if (val > 0x00ffffff) {
+ used = j+4;
+ } else {
+ used = j+3;
+ }
+ } else if (val > 0x000000ff) {
+ used = j+2;
+ } else {
+ used = j+1;
+ }
+ }
+ if (used < _libcap_min_ext_flag_size) {
+ used = _libcap_min_ext_flag_size;
+ }
+ return (ssize_t)(CAP_EXT_MAGIC_SIZE + 1+ NUMBER_OF_CAP_SETS * used);
+}
+
/*
* return size of external capability set
*/
ssize_t cap_size(cap_t cap_d)
{
- if (good_cap_t(cap_d)) {
- size_t j, used;
- for (j=used=0; j<CAP_SET_SIZE; j+=sizeof(__u32)) {
- int i;
- __u32 val = 0;
- for (i=0; i<NUMBER_OF_CAP_SETS; ++i) {
- val |= cap_d->u[j/sizeof(__u32)].flat[i];
- }
- if (val == 0) {
- continue;
- }
- if (val > 0x0000ffff) {
- if (val > 0x00ffffff) {
- used = j+4;
- } else {
- used = j+3;
- }
- } else if (val > 0x000000ff) {
- used = j+2;
- } else {
- used = j+1;
- }
- }
- if (used < _libcap_min_ext_flag_size) {
- used = _libcap_min_ext_flag_size;
- }
- return (ssize_t)(CAP_EXT_MAGIC_SIZE + 1+ NUMBER_OF_CAP_SETS * used);
+ size_t used;
+ if (!good_cap_t(cap_d)) {
+ return ssizeof(struct cap_ext_struct);
}
- return ssizeof(struct cap_ext_struct);
+ _cap_mu_lock(&cap_d->mutex);
+ used = _cap_size_locked(cap_d);
+ _cap_mu_unlock(&cap_d->mutex);
+ return used;
}
/*
@@ -90,10 +99,11 @@ ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length)
return -1;
}
- csz = cap_size(cap_d);
+ _cap_mu_lock(&cap_d->mutex);
+ csz = _cap_size_locked(cap_d);
if (csz > length) {
errno = EINVAL;
- return -1;
+ _cap_mu_unlock_return(&cap_d->mutex, -1);
}
len_set = (csz - (CAP_EXT_MAGIC_SIZE+1))/NUMBER_OF_CAP_SETS;
@@ -122,7 +132,7 @@ ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length)
}
/* All done: return length of external representation */
- return csz;
+ _cap_mu_unlock_return(&cap_d->mutex, csz);
}
/*