[apparmor] [PATCH 2/4] Add base function to query generic label data under a given key

John Johansen john.johansen at canonical.com
Tue Oct 6 17:14:00 UTC 2015


>From 644c0e75a5a4fd03ab1939e801633dcf2e3ccb20 Mon Sep 17 00:00:00 2001
From: John Johansen <john.johansen at canonical.com>
Date: Thu, 16 Jul 2015 17:26:16 -0700
Subject: [PATCH 2/4] Add base function to query generic label data under a
 given key

Signed-off-by: John Johansen <john.johansen at canonical.com>
---
 libraries/libapparmor/doc/aa_query_label.pod  |   6 ++
 libraries/libapparmor/include/sys/apparmor.h  |  22 +++++
 libraries/libapparmor/src/kernel.c            | 124 ++++++++++++++++++++++++++
 libraries/libapparmor/src/libapparmor.map     |   9 ++
 libraries/libapparmor/swig/SWIG/libapparmor.i |   2 +
 5 files changed, 163 insertions(+)

diff --git a/libraries/libapparmor/doc/aa_query_label.pod b/libraries/libapparmor/doc/aa_query_label.pod
index 900e2d0..8717df0 100644
--- a/libraries/libapparmor/doc/aa_query_label.pod
+++ b/libraries/libapparmor/doc/aa_query_label.pod
@@ -31,6 +31,9 @@ B<#include E<lt>sys/apparmor.hE<gt>>
 B<int aa_query_cmd(const char *cmd, size_t cmd_size, char *query,
 		size_t size, char *buffer, size_t bsize);>
 
+B<extern int aa_query_label_data(const char *label, const char *key,
+		char *buffer, size_t bsize);>
+
 B<int aa_query_label(uint32_t mask, char *query, size_t size,
 		int *allowed, int *audited);>
 
@@ -57,6 +60,9 @@ Link with B<-lapparmor> when compiling.
 The aa_query_cmd function setup and does the raw query of the kernel. It is
 the basis of the other query_X functions.
 
+The aa_query_label_data function does a raw query of any extra data
+stored as I<key> in the label.
+
 The aa_query_label function fetches the current permissions granted by the
 specified I<label> in the I<query> string.
 
diff --git a/libraries/libapparmor/include/sys/apparmor.h b/libraries/libapparmor/include/sys/apparmor.h
index 61629bc..b8d5601 100644
--- a/libraries/libapparmor/include/sys/apparmor.h
+++ b/libraries/libapparmor/include/sys/apparmor.h
@@ -98,6 +98,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);
@@ -115,6 +117,26 @@ 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 n;			/* 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 1de4e54..8371405 100644
--- a/libraries/libapparmor/src/kernel.c
+++ b/libraries/libapparmor/src/kernel.c
@@ -47,6 +47,7 @@
 #define UNCONFINED		"unconfined"
 #define UNCONFINED_SIZE		strlen(UNCONFINED)
 
+
 /**
  * aa_find_mountpoint - find where the apparmor interface filesystem is mounted
  * @mnt: returns buffer with the mountpoint string
@@ -1030,3 +1031,126 @@ 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.
+ *
+ * TODO: fold into calling fn???
+ */
+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: ????
+ *
+ * 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). The data items are broken out into
+ * an ???
+ *
+ * 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_data_info *out)
+{
+	autoclose FILE *file = NULL;
+	const char *p;
+	uint32_t bytes;
+	uint32_t tmp;
+	int fd, ret;
+
+	if (!out)
+		return 0;	/* this should probably be an error ??? */
+
+	memset(out, 0, sizeof(*out));
+
+	/* TODO: fold in if not being used else where */
+	fd = aa_query_label_data_open(label, key);
+	if (fd == -1)
+		return -1;
+
+	file = fdopen(fd, "r+");
+	if (!file)
+		return -1;
+
+	/* TODO: ??? kernel transaction file only support a page size of
+	 *       data. Is it worth doing 2 reads to get the data size
+	 *       allocated correct?
+	 *       Or is it better to just do a single read to a page size
+	 *       buffer and then allocate.
+	 */
+	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->p) {
+		errno = ENOMEM;
+		goto done;
+	}
+
+	for (int i = 0; i < out->n; i++) {
+		memcpy(&tmp, p, sizeof(tmp));
+		out->ents[i].n = le32toh(tmp);
+		p += sizeof(tmp);
+		out->ents[i].entry = p;
+		p += out->entry[i].n;
+	}
+
+done:
+	if (errno)
+		aa_clear_data_info(out);
+
+	return errno ? -1 : 0;
+}
+
+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 98d97ea..9ce35ab 100644
--- a/libraries/libapparmor/src/libapparmor.map
+++ b/libraries/libapparmor/src/libapparmor.map
@@ -87,6 +87,15 @@ APPARMOR_2.10 {
         *;
 } APPARMOR_2.9;
 
+APPARMOR_2.10 {
+  global:
+        aa_query_label_data;
+	aa_clear_label_data;
+  local:
+        *;
+} APPARMOR_2.10;
+
+
 PRIVATE {
 	global:
 		_aa_is_blacklisted;
diff --git a/libraries/libapparmor/swig/SWIG/libapparmor.i b/libraries/libapparmor/swig/SWIG/libapparmor.i
index 3e1950a..7908e07 100644
--- a/libraries/libapparmor/swig/SWIG/libapparmor.i
+++ b/libraries/libapparmor/swig/SWIG/libapparmor.i
@@ -70,5 +70,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,
+			       char *buffer, size_t bsize);
 
 %exception;
-- 
2.1.4





More information about the AppArmor mailing list