[apparmor] [patch 17/26] Move buffer management for the interface to C++ ostringstream class

john.johansen at canonical.com john.johansen at canonical.com
Thu Mar 27 15:45:30 UTC 2014


with sbeattie's pad calculation fix.

Signed-off-by: John Johansen <john.johansen at canonical.com>
---
 parser/parser.h           |    5 
 parser/parser_interface.c |  510 +++++++++++++---------------------------------
 parser/parser_policy.c    |    8 
 3 files changed, 151 insertions(+), 372 deletions(-)

--- 2.9-test.orig/parser/parser.h
+++ 2.9-test/parser/parser.h
@@ -415,9 +415,8 @@
 extern int profile_merge_rules(Profile *prof);
 
 /* parser_interface.c */
-typedef struct __sdserialize sd_serialize;
 extern int load_profile(int option, Profile *prof);
-extern int sd_serialize_profile(sd_serialize *p, Profile *prof,
+extern void sd_serialize_profile(std::ostringstream &buf, Profile *prof,
 				int flatten);
 extern int sd_load_buffer(int option, char *buffer, int size);
 extern int cache_fd;
@@ -438,7 +437,7 @@
 extern int merge_hat_rules(Profile *prof);
 extern Profile *merge_policy(Profile *a, Profile *b);
 extern int load_policy(int option);
-extern int load_hats(sd_serialize *p, Profile *prof);
+extern int load_hats(std::ostringstream &buf, Profile *prof);
 extern int load_flattened_hats(Profile *prof, int option);
 extern void dump_policy_hats(Profile *prof);
 extern void dump_policy_names(void);
--- 2.9-test.orig/parser/parser_interface.c
+++ 2.9-test/parser/parser_interface.c
@@ -27,6 +27,9 @@
 #include <libintl.h>
 #define _(s) gettext(s)
 
+#include <string>
+#include <sstream>
+
 #include "parser.h"
 #include "profile.h"
 #include "libapparmor_re/apparmor_re.h"
@@ -41,8 +44,6 @@
 #define _(s) gettext(s)
 
 
-#define BUFFERINC 65536
-//#define BUFFERINC 16
 
 
 #define SD_CODE_SIZE (sizeof(u8))
@@ -194,301 +195,172 @@
 	"SD_OFFSET"
 };
 
-/* Currently we will just use a contiguous block of memory
-   be we are going to just hide this for the moment.  */
-struct __sdserialize {
-	u8 *buffer;
-	u8 *pos;
-	u8 *extent;
-};
-
-sd_serialize *alloc_sd_serial(void)
-{
-	sd_serialize *p = (sd_serialize *) calloc(1, sizeof(sd_serialize));
-	if (!p)
-		return NULL;
-	p->buffer = (u8 *) malloc(BUFFERINC);
-	if (!p->buffer) {
-		free(p);
-		return NULL;
-	}
-	p->pos = p->buffer;
-	p->extent = p->buffer + BUFFERINC;
-	return p;
-}
-
-void free_sd_serial(sd_serialize *p)
-{
-	if (p) {
-		if (p->buffer)
-			free(p->buffer);
-		free(p);
-	}
-}
 
-/*check if something of size length is in sd_serial bounds */
-static inline int sd_inbounds(sd_serialize *p, int size)
+inline void sd_write8(std::ostringstream &buf, u8 b)
 {
-	return (p->pos + size <= p->extent);
+	buf.write((const char *) &b, 1);
 }
 
-static inline void sd_inc(sd_serialize *p, int size)
+inline void sd_write16(std::ostringstream &buf, u16 b)
 {
-	if (sd_inbounds(p, size)) {
-		p->pos += size;
-	} else {
-		PERROR(_("PANIC bad increment buffer %p pos %p ext %p size %d res %p\n"),
-		       p->buffer, p->pos, p->extent, size, p->pos + size);
-		exit(-1);
-	}
+	u16 tmp;
+	tmp = cpu_to_le16(b);
+	buf.write((const char *) &tmp, 2);
 }
 
-inline long sd_serial_size(sd_serialize *p)
+inline void sd_write32(std::ostringstream &buf, u32 b)
 {
-	return (long) (p->pos) - (long) (p->buffer);
+	u32 tmp;
+	tmp = cpu_to_le32(b);
+	buf.write((const char *) &tmp, 4);
 }
 
-/* routines for writing data to the serialization buffer */
-inline int sd_prepare_write(sd_serialize *p, enum sd_code code, size_t size)
+inline void sd_write64(std::ostringstream &buf, u64 b)
 {
-	int num = (size / BUFFERINC) + 1;
-	if (p->pos + SD_CODE_SIZE + size > p->extent) {
-		long pos;
-		/* try and reallocate the buffer */
-		u8 *buffer = (u8 *) malloc((long)(p->extent) - (long)(p->buffer) + (BUFFERINC * num));
-		memcpy(buffer, p->buffer, (long)(p->extent) - (long)(p->buffer));
-
-		pos = (long)(p->pos) - (long)(p->buffer);
-		if (buffer == NULL || errno == ENOMEM)
-			return 0;
-
-		p->extent = buffer + ((long)(p->extent) - (long)(p->buffer)) + (BUFFERINC * num);
-		free(p->buffer);
-		p->buffer = buffer;
-		p->pos = buffer + pos;
-	}
-	*(u8 *) (p->pos) = code;
-	sd_inc(p, SD_CODE_SIZE);
-	return 1;
+	u64 tmp;
+	tmp = cpu_to_le64(b);
+	buf.write((const char *) &tmp, 8);
 }
 
-inline int sd_write8(sd_serialize *p, u8 b)
+inline void sd_write_uint8(std::ostringstream &buf, u8 b)
 {
-	u8 *c;
-	if (!sd_prepare_write(p, SD_U8, sizeof(b)))
-		return 0;
-	c = (u8 *) p->pos;
-	*c = b;
-	sd_inc(p, 1);
-	return 1;
+	sd_write8(buf, SD_U8);
+	sd_write8(buf, b);
 }
 
-inline int sd_write16(sd_serialize *p, u16 b)
+inline void sd_write_uint16(std::ostringstream &buf, u16 b)
 {
-	u16 tmp;
-	if (!sd_prepare_write(p, SD_U16, sizeof(b)))
-		return 0;
-	tmp = cpu_to_le16(b);
-	memcpy(p->pos, &tmp, sizeof(tmp));
-	sd_inc(p, sizeof(tmp));
-	return 1;
+	sd_write8(buf, SD_U16);
+	sd_write16(buf, b);
 }
 
-inline int sd_write32(sd_serialize *p, u32 b)
+inline void sd_write_uint32(std::ostringstream &buf, u32 b)
 {
-	u32 tmp;
-	if (!sd_prepare_write(p, SD_U32, sizeof(b)))
-		return 0;
-	tmp = cpu_to_le32(b);
-	memcpy(p->pos, &tmp, sizeof(tmp));
-	sd_inc(p, sizeof(tmp));
-	return 1;
+	sd_write8(buf, SD_U32);
+	sd_write32(buf, b);
 }
 
-inline int sd_write64(sd_serialize *p, u64 b)
+inline void sd_write_uint64(std::ostringstream &buf, u64 b)
 {
-	u64 tmp;
-	if (!sd_prepare_write(p, SD_U64, sizeof(b)))
-		return 0;
-	tmp = cpu_to_le64(b);
-	memcpy(p->pos, &tmp, sizeof(tmp));
-	sd_inc(p, sizeof(tmp));
-	return 1;
+	sd_write8(buf, SD_U64);
+	sd_write64(buf, b);
 }
 
-inline int sd_write_name(sd_serialize *p, const char *name)
+inline void sd_write_name(std::ostringstream &buf, const char *name)
 {
-	long size = 0;
 	PDEBUG("Writing name '%s'\n", name);
 	if (name) {
-		u16 tmp;
-		size = strlen(name) + 1;
-		if (!sd_prepare_write(p, SD_NAME, SD_STR_LEN + size))
-			return 0;
-		tmp = cpu_to_le16(size);
-		memcpy(p->pos, &tmp, sizeof(tmp));
-		sd_inc(p, sizeof(tmp));
-		memcpy(p->pos, name, size);
-		sd_inc(p, size);
+		sd_write8(buf, SD_NAME);
+		sd_write16(buf, strlen(name) + 1);
+		buf.write(name, strlen(name) + 1);
 	}
-	return 1;
 }
 
-inline int sd_write_blob(sd_serialize *p, void *b, int buf_size, char *name)
+inline void sd_write_blob(std::ostringstream &buf, void *b, int buf_size, char *name)
 {
-	u32 tmp;
-	if (!sd_write_name(p, name))
-		return 0;
-	if (!sd_prepare_write(p, SD_BLOB, 4 + buf_size))
-		return 0;
-	tmp = cpu_to_le32(buf_size);
-	memcpy(p->pos, &tmp, sizeof(tmp));
-	sd_inc(p, sizeof(tmp));
-	memcpy(p->pos, b, buf_size);
-	sd_inc(p, buf_size);
-	return 1;
+	sd_write_name(buf, name);
+	sd_write8(buf, SD_BLOB);
+	sd_write32(buf, buf_size);
+	buf.write((const char *) b, buf_size);
 }
 
+
+static char zeros[64];
 #define align64(X) (((X) + (typeof(X)) 7) & ~((typeof(X)) 7))
-inline int sd_write_aligned_blob(sd_serialize *p, void *b, int buf_size,
+inline void sd_write_aligned_blob(std::ostringstream &buf, void *b, int b_size,
 				 const char *name)
 {
-	size_t pad;
-	u32 tmp;
-	if (!sd_write_name(p, name))
-		return 0;
-	pad = align64(p->pos + 5 - p->buffer) - (p->pos + 5 - p->buffer);
-	if (!sd_prepare_write(p, SD_BLOB, 4 + buf_size + pad))
-		return 0;
-	tmp = cpu_to_le32(buf_size + pad);
-	memcpy(p->pos, &tmp, sizeof(tmp));
-	sd_inc(p, sizeof(tmp));
-	memset(p->pos, 0, pad);
-	sd_inc(p, pad);
-	memcpy(p->pos, b, buf_size);
-	sd_inc(p, buf_size);
-	return 1;
+	sd_write_name(buf, name);
+	/* pad calculation MUST come after name is written */
+	size_t pad = align64(buf.tellp() + ((std::streamoff) 5l)) - (buf.tellp() + ((std::streamoff) 5l));
+	sd_write8(buf, SD_BLOB);
+	sd_write32(buf, b_size + pad);
+	buf.write(zeros, pad);
+	buf.write((const char *) b, b_size);
 }
 
-static int sd_write_strn(sd_serialize *p, char *b, int size, const char *name)
+static void sd_write_strn(std::ostringstream &buf, char *b, int size, const char *name)
 {
-	u16 tmp;
-	if (!sd_write_name(p, name))
-		return 0;
-	if (!sd_prepare_write(p, SD_STRING, SD_STR_LEN + size))
-		return 0;
-	tmp = cpu_to_le16(size);
-	memcpy(p->pos, &tmp, sizeof(tmp));
-	sd_inc(p, sizeof(tmp));
-	memcpy(p->pos, b, size);
-	sd_inc(p, size);
-	return 1;
+	sd_write_name(buf, name);
+	sd_write8(buf, SD_STRING);
+	sd_write16(buf, size);
+	buf.write(b, size);
 }
 
-inline int sd_write_string(sd_serialize *p, char *b, const char *name)
+inline void sd_write_string(std::ostringstream &buf, char *b, const char *name)
 {
-	return sd_write_strn(p, b, strlen(b) + 1, name);
+	sd_write_strn(buf, b, strlen(b) + 1, name);
 }
 
-inline int sd_write_struct(sd_serialize *p, const char *name)
+inline void sd_write_struct(std::ostringstream &buf, const char *name)
 {
-	if (!sd_write_name(p, name))
-		return 0;
-	if (!sd_prepare_write(p, SD_STRUCT, 0))
-		return 0;
-	return 1;
+	sd_write_name(buf, name);
+	sd_write8(buf, SD_STRUCT);
 }
 
-inline int sd_write_structend(sd_serialize *p)
+inline void sd_write_structend(std::ostringstream &buf)
 {
-	if (!sd_prepare_write(p, SD_STRUCTEND, 0))
-		return 0;
-	return 1;
+	sd_write8(buf, SD_STRUCTEND);
 }
 
-inline int sd_write_array(sd_serialize *p, const char *name, int size)
+inline void sd_write_array(std::ostringstream &buf, const char *name, int size)
 {
-	u16 tmp;
-	if (!sd_write_name(p, name))
-		return 0;
-	if (!sd_prepare_write(p, SD_ARRAY, 2))
-		return 0;
-	tmp = cpu_to_le16(size);
-	memcpy(p->pos, &tmp, sizeof(tmp));
-	sd_inc(p, sizeof(tmp));
-	return 1;
+	sd_write_name(buf, name);
+	sd_write8(buf, SD_ARRAY);
+	sd_write16(buf, size);
 }
 
-inline int sd_write_arrayend(sd_serialize *p)
+inline void sd_write_arrayend(std::ostringstream &buf)
 {
-	if (!sd_prepare_write(p, SD_ARRAYEND, 0))
-		return 0;
-	return 1;
+	sd_write8(buf, SD_ARRAYEND);
 }
 
-inline int sd_write_list(sd_serialize *p, const char *name)
+inline void sd_write_list(std::ostringstream &buf, const char *name)
 {
-	if (!sd_write_name(p, name))
-		return 0;
-	if (!sd_prepare_write(p, SD_LIST, 0))
-		return 0;
-	return 1;
+	sd_write_name(buf, name);
+	sd_write8(buf, SD_LIST);
 }
 
-inline int sd_write_listend(sd_serialize *p)
+inline void sd_write_listend(std::ostringstream &buf)
 {
-	if (!sd_prepare_write(p, SD_LISTEND, 0))
-		return 0;
-	return 1;
+	sd_write8(buf, SD_LISTEND);
 }
 
-int sd_serialize_dfa(sd_serialize *p, void *dfa, size_t size)
+void sd_serialize_dfa(std::ostringstream &buf, void *dfa, size_t size)
 {
-	if (dfa && !sd_write_aligned_blob(p, dfa, size, "aadfa"))
-		return 0;
-
-	return 1;
+	if (dfa)
+		sd_write_aligned_blob(buf, dfa, size, "aadfa");
 }
 
-int sd_serialize_rlimits(sd_serialize *p, struct aa_rlimits *limits)
+void sd_serialize_rlimits(std::ostringstream &buf, struct aa_rlimits *limits)
 {
-	int i;
 	if (!limits->specified)
-		return 1;
-	if (!sd_write_struct(p, "rlimits"))
-		return 0;
-	if (!sd_write32(p, limits->specified))
-		return 0;
-	if (!sd_write_array(p, NULL, RLIM_NLIMITS))
-		return 0;
-	for (i = 0; i < RLIM_NLIMITS; i++) {
-		if (!sd_write64(p, limits->limits[i]))
-			return 0;
-	}
-	if (!sd_write_arrayend(p))
-		return 0;
-	if (!sd_write_structend(p))
-		return 0;
-	return 1;
+		return;
+
+	sd_write_struct(buf, "rlimits");
+	sd_write_uint32(buf, limits->specified);
+	sd_write_array(buf, NULL, RLIM_NLIMITS);
+	for (int i = 0; i < RLIM_NLIMITS; i++) {
+		sd_write_uint64(buf, limits->limits[i]);
+	}
+	sd_write_arrayend(buf);
+	sd_write_structend(buf);
 }
 
-int sd_serialize_xtable(sd_serialize *p, char **table)
+void sd_serialize_xtable(std::ostringstream &buf, char **table)
 {
-	int count, i;
+	int count;
 	if (!table[4])
-		return 1;
-	if (!sd_write_struct(p, "xtable"))
-		return 0;
+		return;
+	sd_write_struct(buf, "xtable");
 	count = 0;
-	for (i = 4; i < AA_EXEC_COUNT; i++) {
+	for (int i = 4; i < AA_EXEC_COUNT; i++) {
 		if (table[i])
 			count++;
 	}
 
-	if (!sd_write_array(p, NULL, count))
-		return 0;
-
-	for (i = 4; i < count + 4; i++) {
+	sd_write_array(buf, NULL, count);
+	for (int i = 4; i < count + 4; i++) {
 		int len = strlen(table[i]) + 1;
 
 		/* if its a namespace make sure the second : is overwritten
@@ -498,88 +370,45 @@
 			char *tmp = table[i] + 1;
 			strsep(&tmp, ":");
 		}
-		if (!sd_write_strn(p, table[i], len, NULL))
-			return 0;
-
-	}
-	if (!sd_write_arrayend(p))
-		return 0;
-
-	if (!sd_write_structend(p))
-		return 0;
-	return 1;
-}
-
-int count_file_ents(struct cod_entry *list)
-{
-	struct cod_entry *entry;
-	int count = 0;
-	list_for_each(list, entry) {
-		if (entry->pattern_type == ePatternBasic) {
-			count++;
-		}
+		sd_write_strn(buf, table[i], len, NULL);
 	}
-	return count;
+	sd_write_arrayend(buf);
+	sd_write_structend(buf);
 }
 
-int count_tailglob_ents(struct cod_entry *list)
-{
-	struct cod_entry *entry;
-	int count = 0;
-	list_for_each(list, entry) {
-		if (entry->pattern_type == ePatternTailGlob) {
-			count++;
-		}
-	}
-	return count;
-}
-
-int sd_serialize_profile(sd_serialize *p, Profile *profile,
+void sd_serialize_profile(std::ostringstream &buf, Profile *profile,
 			 int flattened)
 {
 	uint64_t allowed_caps;
 
-	if (!sd_write_struct(p, "profile"))
-		return 0;
+	sd_write_struct(buf, "profile");
 	if (flattened) {
 		assert(profile->parent);
-		int res;
-
 		char *name = (char *) malloc(3 + strlen(profile->name) +
 				    strlen(profile->parent->name));
 		if (!name)
-			return 0;
+			return;
 		sprintf(name, "%s//%s", profile->parent->name, profile->name);
-		res = sd_write_string(p, name, NULL);
+		sd_write_string(buf, name, NULL);
 		free(name);
-		if (!res)
-			return 0;
 	} else {
-		if (!sd_write_string(p, profile->name, NULL))
-			return 0;
+		sd_write_string(buf, profile->name, NULL);
 	}
 
 	/* only emit this if current kernel at least supports "create" */
 	if (perms_create) {
 		if (profile->xmatch) {
-			if (!sd_serialize_dfa(p, profile->xmatch, profile->xmatch_size))
-				return 0;
-			if (!sd_write32(p, profile->xmatch_len))
-				return 0;
+			sd_serialize_dfa(buf, profile->xmatch, profile->xmatch_size);
+			sd_write_uint32(buf, profile->xmatch_len);
 		}
 	}
 
-	if (!sd_write_struct(p, "flags"))
-		return 0;
+	sd_write_struct(buf, "flags");
 	/* used to be flags.debug, but that's no longer supported */
-	if (!sd_write32(p, profile->flags.hat))
-		return 0;
-	if (!sd_write32(p, profile->flags.complain))
-		return 0;
-	if (!sd_write32(p, profile->flags.audit))
-		return 0;
-	if (!sd_write_structend(p))
-		return 0;
+	sd_write_uint32(buf, profile->flags.hat);
+	sd_write_uint32(buf, profile->flags.complain);
+	sd_write_uint32(buf, profile->flags.audit);
+	sd_write_structend(buf);
 	if (profile->flags.path) {
 		int flags = 0;
 		if (profile->flags.path & PATH_CHROOT_REL)
@@ -591,102 +420,71 @@
 		if (profile->flags.path & PATH_CHROOT_NSATTACH)
 			flags |= 0x10;
 
-		if (!sd_write_name(p, "path_flags") ||
-		    !sd_write32(p, flags))
-			return 0;
+		sd_write_name(buf, "path_flags");
+		sd_write_uint32(buf, flags);
 	}
 
 #define low_caps(X) ((u32) ((X) & 0xffffffff))
 #define high_caps(X) ((u32) (((X) >> 32) & 0xffffffff))
 	allowed_caps = (profile->caps.allow) & ~profile->caps.deny;
-	if (!sd_write32(p, low_caps(allowed_caps)))
-		return 0;
-	if (!sd_write32(p, low_caps(allowed_caps & profile->caps.audit)))
-		return 0;
-	if (!sd_write32(p, low_caps(profile->caps.deny & profile->caps.quiet)))
-		return 0;
-	if (!sd_write32(p, 0))
-		return 0;
-
-	if (!sd_write_struct(p, "caps64"))
-		return 0;
-	if (!sd_write32(p, high_caps(allowed_caps)))
-		return 0;
-	if (!sd_write32(p, high_caps(allowed_caps & profile->caps.audit)))
-		return 0;
-	if (!sd_write32(p, high_caps(profile->caps.deny & profile->caps.quiet)))
-		return 0;
-	if (!sd_write32(p, 0))
-		return 0;
-	if (!sd_write_structend(p))
-		return 0;
+	sd_write_uint32(buf, low_caps(allowed_caps));
+	sd_write_uint32(buf, low_caps(allowed_caps & profile->caps.audit));
+	sd_write_uint32(buf, low_caps(profile->caps.deny & profile->caps.quiet));
+	sd_write_uint32(buf, 0);
+
+	sd_write_struct(buf, "caps64");
+	sd_write_uint32(buf, high_caps(allowed_caps));
+	sd_write_uint32(buf, high_caps(allowed_caps & profile->caps.audit));
+	sd_write_uint32(buf, high_caps(profile->caps.deny & profile->caps.quiet));
+	sd_write_uint32(buf, 0);
+	sd_write_structend(buf);
 
-	if (!sd_serialize_rlimits(p, &profile->rlimits))
-		return 0;
+	sd_serialize_rlimits(buf, &profile->rlimits);
 
 	if (profile->net.allow && kernel_supports_network) {
 		size_t i;
-		if (!sd_write_array(p, "net_allowed_af", get_af_max()))
-			return 0;
+		sd_write_array(buf, "net_allowed_af", get_af_max());
 		for (i = 0; i < get_af_max(); i++) {
-		    u16 allowed = profile->net.allow[i] &
-			~profile->net.deny[i];
-			if (!sd_write16(p, allowed))
-				return 0;
-			if (!sd_write16(p, allowed & profile->net.audit[i]))
-				return 0;
-			if (!sd_write16(p, profile->net.deny[i] & profile->net.quiet[i]))
-				return 0;
+			u16 allowed = profile->net.allow[i] &
+				~profile->net.deny[i];
+			sd_write_uint16(buf, allowed);
+			sd_write_uint16(buf, allowed & profile->net.audit[i]);
+			sd_write_uint16(buf, profile->net.deny[i] & profile->net.quiet[i]);
 		}
-		if (!sd_write_arrayend(p))
-			return 0;
+		sd_write_arrayend(buf);
 	} else if (profile->net.allow)
 		pwarn(_("profile %s network rules not enforced\n"), profile->name);
 
 	if (profile->policy.dfa) {
-		if (!sd_write_struct(p, "policydb"))
-			return 0;
-		if (!sd_serialize_dfa(p, profile->policy.dfa, profile->policy.size))
-			return 0;
-		if (!sd_write_structend(p))
-			return 0;
+		sd_write_struct(buf, "policydb");
+		sd_serialize_dfa(buf, profile->policy.dfa, profile->policy.size);
+		sd_write_structend(buf);
 	}
 
 	/* either have a single dfa or lists of different entry types */
-	if (!sd_serialize_dfa(p, profile->dfa.dfa, profile->dfa.size))
-		return 0;
-
-	if (!sd_serialize_xtable(p, profile->exec_table))
-		return 0;
+	sd_serialize_dfa(buf, profile->dfa.dfa, profile->dfa.size);
+	sd_serialize_xtable(buf, profile->exec_table);
 
-	if (!sd_write_structend(p))
-		return 0;
-
-	return 1;
+	sd_write_structend(buf);
 }
 
-int sd_serialize_top_profile(sd_serialize *p, Profile *profile)
+void sd_serialize_top_profile(std::ostringstream &buf, Profile *profile)
 {
 	uint32_t version;
 
 	version = ENCODE_VERSION(force_complain, policy_version,
 				 parser_abi_version, kernel_abi_version);
 
-	if (!sd_write_name(p, "version"))
-		return 0;
-
-	if (!sd_write32(p, version))
-		return 0;
+	sd_write_name(buf, "version");
+	sd_write_uint32(buf, version);
 
 	if (profile_ns) {
-		if (!sd_write_string(p, profile_ns, "namespace"))
-			return 0;
+		sd_write_string(buf, profile_ns, "namespace");
 	} else if (profile->ns) {
-		if (!sd_write_string(p, profile->ns, "namespace"))
-			return 0;
+		sd_write_string(buf, profile->ns, "namespace");
 	}
 
-	return sd_serialize_profile(p, profile, profile->parent ? 1 : 0);
+	sd_serialize_profile(buf, profile, profile->parent ? 1 : 0);
 }
 
 int cache_fd = -1;
@@ -694,7 +492,7 @@
 {
 	int fd = -1;
 	int error = -ENOMEM, size, wsize;
-	sd_serialize *work_area;
+	std::ostringstream work_area;
 	char *filename = NULL;
 
 	switch (option) {
@@ -782,26 +580,12 @@
 		if (prof->parent || ns)
 			free(name);
 	} else {
+		sd_serialize_top_profile(work_area, prof);
 
-		work_area = alloc_sd_serial();
-		if (!work_area) {
-			close(fd);
-			PERROR(_("unable to create work area\n"));
-			error = -ENOMEM;
-			goto exit;
-		}
-
-		if (!sd_serialize_top_profile(work_area, prof)) {
-			close(fd);
-			free_sd_serial(work_area);
-			PERROR(_("unable to serialize profile %s\n"),
-			       prof->name);
-			goto exit;
-		}
-
-		size = (long) (work_area->pos) - (long)(work_area->buffer);
+		size = (long) work_area.tellp();
 		if (kernel_load || option == OPTION_STDOUT || option == OPTION_OFILE) {
-			wsize = write(fd, work_area->buffer, size);
+			std::string tmp = work_area.str();
+			wsize = write(fd, tmp.c_str(), size);
 			if (wsize < 0) {
 				error = -errno;
 			} else if (wsize < size) {
@@ -811,7 +595,8 @@
 			}
 		}
 		if (cache_fd != -1) {
-			wsize = write(cache_fd, work_area->buffer, size);
+			std::string tmp = work_area.str();
+			wsize = write(cache_fd, tmp.c_str(), size);
 			if (wsize < 0) {
 				error = -errno;
 			} else if (wsize < size) {
@@ -820,7 +605,6 @@
 				error = -EIO;
 			}
 		}
-		free_sd_serial(work_area);
 	}
 
 	close(fd);
--- 2.9-test.orig/parser/parser_policy.c
+++ 2.9-test/parser/parser_policy.c
@@ -243,14 +243,10 @@
 	return load_policy_list(policy_list, option);
 }
 
-int load_hats(sd_serialize *p, Profile *prof)
+int load_hats(std::ostringstream &buf, Profile *prof)
 {
 	for (ProfileList::iterator i = prof->hat_table.begin(); i != prof->hat_table.end(); i++) {
-		if (!sd_serialize_profile(p, *i, 0)) {
-			PERROR(_("ERROR in profile %s, failed to load\n"),
-			       (*i)->name);
-			return -EINVAL;
-		}
+		sd_serialize_profile(buf, *i, 0);
 	}
 
 	return 0;




More information about the AppArmor mailing list