---
 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

Reply via email to