diff options
author | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
---|---|---|
committer | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
commit | 22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch) | |
tree | bffa27765faf54126ad44bcafa89fadecb7a73d7 /contrib/libs/libcap/cap_extint.c | |
parent | 332b99e2173f0425444abb759eebcb2fafaa9209 (diff) | |
download | ydb-22f8ae0e3f5d68b92aecccdf96c1d841a0334311.tar.gz |
validate canons without yatest_common
Diffstat (limited to 'contrib/libs/libcap/cap_extint.c')
-rw-r--r-- | contrib/libs/libcap/cap_extint.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/contrib/libs/libcap/cap_extint.c b/contrib/libs/libcap/cap_extint.c new file mode 100644 index 0000000000..7d6e7ade05 --- /dev/null +++ b/contrib/libs/libcap/cap_extint.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org> + * + * This file deals with exchanging internal and external + * representations of capability sets. + */ + +#include "libcap.h" + +/* + * External representation for capabilities. (exported as a fixed + * length) + */ +#define CAP_EXT_MAGIC "\220\302\001\121" +#define CAP_EXT_MAGIC_SIZE 4 +const static __u8 external_magic[CAP_EXT_MAGIC_SIZE+1] = CAP_EXT_MAGIC; + +struct cap_ext_struct { + __u8 magic[CAP_EXT_MAGIC_SIZE]; + __u8 length_of_capset; + /* + * note, we arrange these so the caps are stacked with byte-size + * resolution + */ + __u8 bytes[CAP_SET_SIZE][NUMBER_OF_CAP_SETS]; +}; + +/* + * return size of external capability set + */ + +ssize_t cap_size(cap_t caps) +{ + return ssizeof(struct cap_ext_struct); +} + +/* + * Copy the internal (cap_d) capability set into an external + * representation. The external representation is portable to other + * Linux architectures. + */ + +ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length) +{ + struct cap_ext_struct *result = (struct cap_ext_struct *) cap_ext; + int i; + + /* valid arguments? */ + if (!good_cap_t(cap_d) || length < ssizeof(struct cap_ext_struct) + || cap_ext == NULL) { + errno = EINVAL; + return -1; + } + + /* fill external capability set */ + memcpy(&result->magic, external_magic, CAP_EXT_MAGIC_SIZE); + result->length_of_capset = CAP_SET_SIZE; + + for (i=0; i<NUMBER_OF_CAP_SETS; ++i) { + size_t j; + for (j=0; j<CAP_SET_SIZE; ) { + __u32 val; + + val = cap_d->u[j/sizeof(__u32)].flat[i]; + + result->bytes[j++][i] = val & 0xFF; + result->bytes[j++][i] = (val >>= 8) & 0xFF; + result->bytes[j++][i] = (val >>= 8) & 0xFF; + result->bytes[j++][i] = (val >> 8) & 0xFF; + } + } + + /* All done: return length of external representation */ + return (ssizeof(struct cap_ext_struct)); +} + +/* + * Import an external representation to produce an internal rep. + * the internal rep should be liberated with cap_free(). + */ + +cap_t cap_copy_int(const void *cap_ext) +{ + const struct cap_ext_struct *export = + (const struct cap_ext_struct *) cap_ext; + cap_t cap_d; + int set, blen; + + /* Does the external representation make sense? */ + if ((export == NULL) + || memcmp(export->magic, external_magic, CAP_EXT_MAGIC_SIZE)) { + errno = EINVAL; + return NULL; + } + + /* Obtain a new internal capability set */ + if (!(cap_d = cap_init())) + return NULL; + + blen = export->length_of_capset; + for (set=0; set<NUMBER_OF_CAP_SETS; ++set) { + unsigned blk; + int bno = 0; + for (blk=0; blk<(CAP_SET_SIZE/sizeof(__u32)); ++blk) { + __u32 val = 0; + + if (bno != blen) + val = export->bytes[bno++][set]; + if (bno != blen) + val |= export->bytes[bno++][set] << 8; + if (bno != blen) + val |= export->bytes[bno++][set] << 16; + if (bno != blen) + val |= export->bytes[bno++][set] << 24; + + cap_d->u[blk].flat[set] = val; + } + } + + /* all done */ + return cap_d; +} + |