--- libraries/libapparmor/doc/aa_query_label.pod | 6 ++ libraries/libapparmor/include/sys/apparmor.h | 19 ++++ libraries/libapparmor/src/kernel.c | 119 ++++++++++++++++++++++++++ libraries/libapparmor/src/libapparmor.map | 2 + libraries/libapparmor/swig/SWIG/libapparmor.i | 2 + 5 files changed, 148 insertions(+)
diff --git a/libraries/libapparmor/doc/aa_query_label.pod b/libraries/libapparmor/doc/aa_query_label.pod index 73f430b..eadb8cd 100644 --- a/libraries/libapparmor/doc/aa_query_label.pod +++ b/libraries/libapparmor/doc/aa_query_label.pod @@ -38,6 +38,9 @@ B<int aa_query_cmd(const char *cmd, size_t cmd_size, char *query, B<int aa_query_label(uint32_t mask, char *query, size_t size, int *allowed, int *audited);> +B<int aa_query_label_data(const char *label, const char *key, + char *buffer, size_t bsize);> + B<int aa_query_file_path(uint32_t mask, const char *label, size_t label_len, const char *path, int *allowed, int *audited);> @@ -60,6 +63,9 @@ the basis of the other query functions. The B<aa_query_label> function fetches the current permissions granted by the specified I<label> in the I<query> string. +The B<aa_query_label_data> function does a raw query of any extra data stored +as I<key> in the label. + The query is a raw binary formatted query, containing the label and permission query to make. The returned I<allowed> and I<audited> values are interpreted boolean values, simply stating whether the query is allowed and diff --git a/libraries/libapparmor/include/sys/apparmor.h b/libraries/libapparmor/include/sys/apparmor.h index 5e43ba2..eda9441 100644 --- a/libraries/libapparmor/include/sys/apparmor.h +++ b/libraries/libapparmor/include/sys/apparmor.h @@ -100,6 +100,8 @@ extern int aa_getpeercon(int fd, char **label, char **mode); */ #define AA_QUERY_CMD_LABEL "label" #define AA_QUERY_CMD_LABEL_SIZE sizeof(AA_QUERY_CMD_LABEL) +#define AA_QUERY_CMD_DATA "data" +#define AA_QUERY_CMD_DATA_SIZE sizeof(AA_QUERY_CMD_DATA) extern int aa_query_cmd(const char *cmd, size_t cmd_size, char *query, size_t size, char *buffer, size_t bsize); @@ -117,6 +119,23 @@ extern int aa_query_link_path_len(const char *label, size_t label_len, extern int aa_query_link_path(const char *label, const char *target, const char *link, int *allowed, int *audited); + +typedef struct { + size_t size; /* length of s */ + const char *entry; /* not necessarily NULL-terminated */ +} aa_label_data_ent; + +typedef struct { + char *data; /* free data */ + size_t n; /* number of ents */ + aa_label_data_ent *ents; /* free vec of entries */ +} aa_label_data_info; + +extern int aa_query_label_data(const char *label, const char *key, + aa_label_data_info *out); +extern void aa_clear_label_data(aa_label_data_info *info); + + #define __macroarg_counter(Y...) __macroarg_count1 ( , ##Y) #define __macroarg_count1(Y...) __macroarg_count2 (Y, 16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) #define __macroarg_count2(_,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,n,Y...) n diff --git a/libraries/libapparmor/src/kernel.c b/libraries/libapparmor/src/kernel.c index 1fe1b61..fda4f0b 100644 --- a/libraries/libapparmor/src/kernel.c +++ b/libraries/libapparmor/src/kernel.c @@ -1072,3 +1072,122 @@ int aa_query_link_path(const char *label, const char *target, const char *link, strlen(target), link, strlen(link), allowed, audited); } + +/** + * aa_query_label_data_open - query + * @label: security label + * @key: key of data blob to lookup + * + * Returns: fd waiting to read data else -1 and sets errno. + */ +static int aa_query_label_data_open(const char *label, const char *key) +{ + autofree char *query = NULL; + + size_t label_len = strlen(label); + size_t key_len = strlen(key); + + /* + 1s for null separators */ + size_t size = AA_QUERY_CMD_DATA_SIZE + label_len + 1 + key_len + 1; + query = malloc(size + 1); + if (!query) + return -1; + memcpy(query + AA_QUERY_CMD_DATA_SIZE, label, label_len + 1); + memcpy(query + AA_QUERY_CMD_DATA_SIZE + label_len + 1, key, key_len + 1); + return aa_query_cmd_open(AA_QUERY_CMD_DATA, AA_QUERY_CMD_DATA_SIZE, query, + size); +} + +/** + * aa_query_label_data - query data associated with @key for @label + * @key: key of data blob to get data for + * @out: data found if any + * + * Returns: 0 on success, non-zero on failure + * + * This fn will extract any data associated with @key in @label. Since + * @label is a compound label there maybe multiple data items associated + * with the key (up to one per profile). + * + * When multiple items are returned for @key, this function does not + * provide any indication of which subcomponents of the @label the data + * belonged to. To obtain that information use the compound label iterator + * and call this function once for each iteration. + */ +int aa_query_label_data(const char *label, const char *key, aa_label_data_info *out) +{ + autofclose FILE *file = NULL; + const char *p; + uint32_t bytes; + uint32_t tmp; + int fd; + + if (!out) + return 0; + + memset(out, 0, sizeof(*out)); + + fd = aa_query_label_data_open(label, key); + if (fd == -1) + return -1; + + file = fdopen(fd, "r+"); + if (!file) + return -1; + + if (fread(&tmp, sizeof(tmp), 1, file) != 1) { + errno = EPROTO; + goto done; + } + + bytes = le32toh(tmp); + out->data = malloc(bytes); + if (!out->data) { + errno = ENOMEM; + goto done; + } + + if (fread(out->data, sizeof(char), bytes, file) != bytes) { + errno = EPROTO; + goto done; + } + + p = out->data; + memcpy(&tmp, p, sizeof(tmp)); + out->n = le32toh(tmp); + p += sizeof(tmp); + + out->ents = malloc(out->n * sizeof(*out->ents)); + if (!out->data) { + errno = ENOMEM; + goto done; + } + + for (int i = 0; i < out->n; i++) { + memcpy(&tmp, p, sizeof(tmp)); + out->ents[i].size = le32toh(tmp); + p += sizeof(tmp); + out->ents[i].entry = p; + p += out->ents[i].size; + } + +done: + if (errno) + aa_clear_label_data(out); + + return errno ? -1 : 0; +} + +/** + * aa_clear_label_data - release resources associated with @info + * @info: info struct + * + * Releases allocated memory associated with @info. + */ +void aa_clear_label_data(aa_label_data_info *info) +{ + free(info->ents); + free(info->data); + + memset(info, 0, sizeof(*info)); +} diff --git a/libraries/libapparmor/src/libapparmor.map b/libraries/libapparmor/src/libapparmor.map index 69207d3..3ce786f 100644 --- a/libraries/libapparmor/src/libapparmor.map +++ b/libraries/libapparmor/src/libapparmor.map @@ -98,6 +98,8 @@ APPARMOR_2.11 { APPARMOR_2.12 { global: aa_query_cmd; + aa_clear_label_data; + aa_query_label_data; local: *; } APPARMOR_2.11; diff --git a/libraries/libapparmor/swig/SWIG/libapparmor.i b/libraries/libapparmor/swig/SWIG/libapparmor.i index 9165882..a2d85b4 100644 --- a/libraries/libapparmor/swig/SWIG/libapparmor.i +++ b/libraries/libapparmor/swig/SWIG/libapparmor.i @@ -72,5 +72,7 @@ extern int aa_query_link_path_len(const char *label, size_t label_len, int *allowed, int *audited); extern int aa_query_link_path(const char *label, const char *target, const char *link, int *allowed, int *audited); +extern int aa_query_label_data(const char *label, const char *key, + aa_label_data_info *out); %exception; -- 2.9.3 -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor