diff --git a/libselinux/src/label.c b/libselinux/src/label.c
index 963bfcb..11324ea 100644
--- a/libselinux/src/label.c
+++ b/libselinux/src/label.c
@@ -209,7 +209,7 @@ int selabel_validate(struct selabel_handle *rec,
 	if (!rec->validating || contexts->validated)
 		goto out;
 
-	rc = selinux_validate(&contexts->ctx_raw);
+	rc = selinux_validate(&contexts->ctx_raw.str);
 	if (rc < 0)
 		goto out;
 
@@ -248,7 +248,7 @@ static int selabel_fini(struct selabel_handle *rec,
 		return -1;
 
 	if (translating && !lr->ctx_trans &&
-	    selinux_raw_to_trans_context(lr->ctx_raw, &lr->ctx_trans))
+	    selinux_raw_to_trans_context(lr->ctx_raw.str, &lr->ctx_trans))
 		return -1;
 
 	return 0;
@@ -369,7 +369,7 @@ int selabel_lookup_raw(struct selabel_handle *rec, char **con,
 	if (!lr)
 		return -1;
 
-	*con = strdup(lr->ctx_raw);
+	*con = strdup(lr->ctx_raw.str);
 	return *con ? 0 : -1;
 }
 
@@ -429,7 +429,7 @@ int selabel_lookup_best_match_raw(struct selabel_handle *rec, char **con,
 	if (!lr)
 		return -1;
 
-	*con = strdup(lr->ctx_raw);
+	*con = strdup(lr->ctx_raw.str);
 	return *con ? 0 : -1;
 }
 
diff --git a/libselinux/src/label_android_property.c b/libselinux/src/label_android_property.c
index 290b438..af0b9a8 100644
--- a/libselinux/src/label_android_property.c
+++ b/libselinux/src/label_android_property.c
@@ -16,7 +16,7 @@
 /* A property security context specification. */
 typedef struct spec {
 	struct selabel_lookup_rec lr;	/* holds contexts for lookup result */
-	char *property_key;		/* property key string */
+	struct len_str property_key;		/* property key string */
 } spec_t;
 
 /* Our stored configuration */
@@ -33,13 +33,13 @@ static int cmp(const void *A, const void *B)
 {
 	const struct spec *sp1 = A, *sp2 = B;
 
-	if (strncmp(sp1->property_key, "*", 1) == 0)
+	if (strncmp(sp1->property_key.str, "*", 1) == 0)
 		return 1;
-	if (strncmp(sp2->property_key, "*", 1) == 0)
+	if (strncmp(sp2->property_key.str, "*", 1) == 0)
 		return -1;
 
-	size_t L1 = strlen(sp1->property_key);
-	size_t L2 = strlen(sp2->property_key);
+	size_t L1 = sp1->property_key.len;
+	size_t L2 = sp2->property_key.len;
 
 	return (L1 < L2) - (L1 > L2);
 }
@@ -56,23 +56,23 @@ static int nodups_specs(struct saved_data *data, const char *path)
 	for (ii = 0; ii < data->nspec; ii++) {
 		curr_spec = &spec_arr[ii];
 		for (jj = ii + 1; jj < data->nspec; jj++) {
-			if (!strcmp(spec_arr[jj].property_key,
-					    curr_spec->property_key)) {
+			if (len_str_eq(&spec_arr[jj].property_key,
+					    &curr_spec->property_key)) {
 				rc = -1;
 				errno = EINVAL;
-				if (strcmp(spec_arr[jj].lr.ctx_raw,
-						    curr_spec->lr.ctx_raw)) {
+				if (!len_str_eq(&spec_arr[jj].lr.ctx_raw,
+						    &curr_spec->lr.ctx_raw)) {
 					selinux_log
 						(SELINUX_ERROR,
 						 "%s: Multiple different specifications for %s  (%s and %s).\n",
-						 path, curr_spec->property_key,
-						 spec_arr[jj].lr.ctx_raw,
-						 curr_spec->lr.ctx_raw);
+						 path, curr_spec->property_key.str,
+						 spec_arr[jj].lr.ctx_raw.str,
+						 curr_spec->lr.ctx_raw.str);
 				} else {
 					selinux_log
 						(SELINUX_ERROR,
 						 "%s: Multiple same specifications for %s.\n",
-						 path, curr_spec->property_key);
+						 path, curr_spec->property_key.str);
 				}
 			}
 		}
@@ -85,7 +85,7 @@ static int process_line(struct selabel_handle *rec,
 			int pass, unsigned lineno)
 {
 	int items;
-	char *prop = NULL, *context = NULL;
+	struct len_str *prop = { 0 }, *context = { 0 };
 	struct saved_data *data = (struct saved_data *)rec->data;
 	spec_t *spec_arr = data->spec_arr;
 	unsigned int nspec = data->nspec;
@@ -118,14 +118,14 @@ static int process_line(struct selabel_handle *rec,
 		free(context);
 	} else if (pass == 1) {
 		/* On the second pass, process and store the specification in spec. */
-		spec_arr[nspec].property_key = prop;
-		spec_arr[nspec].lr.ctx_raw = context;
+		memcpy(&spec_arr[nspec].property_key, prop, sizeof(*prop));
+		memcpy(&spec_arr[nspec].lr.ctx_raw, context, sizeof(*context));
 
 		if (rec->validating) {
 			if (selabel_validate(rec, &spec_arr[nspec].lr) < 0) {
 				selinux_log(SELINUX_ERROR,
 					    "%s:  line %u has invalid context %s\n",
-					    path, lineno, spec_arr[nspec].lr.ctx_raw);
+					    path, lineno, spec_arr[nspec].lr.ctx_raw.str);
 				errno = EINVAL;
 				return -1;
 			}
@@ -233,8 +233,8 @@ static void closef(struct selabel_handle *rec)
 
 	for (i = 0; i < data->nspec; i++) {
 		spec = &data->spec_arr[i];
-		free(spec->property_key);
-		free(spec->lr.ctx_raw);
+		free(spec->property_key.str);
+		free(spec->lr.ctx_raw.str);
 		free(spec->lr.ctx_trans);
 	}
 
@@ -259,11 +259,11 @@ static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
 	}
 
 	for (i = 0; i < data->nspec; i++) {
-		if (strncmp(spec_arr[i].property_key, key,
-			    strlen(spec_arr[i].property_key)) == 0) {
+		if (strncmp(spec_arr[i].property_key.str, key,
+			    spec_arr[i].property_key.len) == 0) {
 			break;
 		}
-		if (strncmp(spec_arr[i].property_key, "*", 1) == 0)
+		if (strncmp(spec_arr[i].property_key.str, "*", 1) == 0)
 			break;
 	}
 
diff --git a/libselinux/src/label_db.c b/libselinux/src/label_db.c
index 1155bcc..c700aca 100644
--- a/libselinux/src/label_db.c
+++ b/libselinux/src/label_db.c
@@ -153,7 +153,8 @@ process_line(const char *path, char *line_buf, unsigned int line_num,
 
 	free(type);
 	spec->key = key;
-	spec->lr.ctx_raw = context;
+	spec->lr.ctx_raw.str = context;
+	spec->lr.ctx_raw.len = strlen(context);
 
 	catalog->nspec++;
 
@@ -181,7 +182,7 @@ db_close(struct selabel_handle *rec)
 	for (i = 0; i < catalog->nspec; i++) {
 		spec = &catalog->specs[i];
 		free(spec->key);
-		free(spec->lr.ctx_raw);
+		free(spec->lr.ctx_raw.str);
 		free(spec->lr.ctx_trans);
 	}
 	free(catalog);
@@ -333,7 +334,7 @@ out_error:
 		spec_t	       *spec = &catalog->specs[i];
 
 		free(spec->key);
-		free(spec->lr.ctx_raw);
+		free(spec->lr.ctx_raw.str);
 		free(spec->lr.ctx_trans);
 	}
 	free(catalog);
diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
index 68c566b..ade07d8 100644
--- a/libselinux/src/label_file.c
+++ b/libselinux/src/label_file.c
@@ -71,25 +71,24 @@ static int nodups_specs(struct saved_data *data, const char *path)
 	for (ii = 0; ii < data->nspec; ii++) {
 		curr_spec = &spec_arr[ii];
 		for (jj = ii + 1; jj < data->nspec; jj++) {
-			if ((!strcmp(spec_arr[jj].regex_str,
-				curr_spec->regex_str))
+			if (len_str_eq(&spec_arr[jj].regex_str, &curr_spec->regex_str)
 			    && (!spec_arr[jj].mode || !curr_spec->mode
 				|| spec_arr[jj].mode == curr_spec->mode)) {
 				rc = -1;
 				errno = EINVAL;
-				if (strcmp(spec_arr[jj].lr.ctx_raw,
-					    curr_spec->lr.ctx_raw)) {
+				if (!len_str_eq(&spec_arr[jj].lr.ctx_raw,
+					    &curr_spec->lr.ctx_raw)) {
 					COMPAT_LOG
 						(SELINUX_ERROR,
 						 "%s: Multiple different specifications for %s  (%s and %s).\n",
-						 path, curr_spec->regex_str,
-						 spec_arr[jj].lr.ctx_raw,
-						 curr_spec->lr.ctx_raw);
+						 path, curr_spec->regex_str.str,
+						 spec_arr[jj].lr.ctx_raw.str,
+						 curr_spec->lr.ctx_raw.str);
 				} else {
 					COMPAT_LOG
 						(SELINUX_ERROR,
 						 "%s: Multiple same specifications for %s.\n",
-						 path, curr_spec->regex_str);
+						 path, curr_spec->regex_str.str);
 				}
 			}
 		}
@@ -475,12 +474,13 @@ static int read_binary_file(struct selabel_handle *rec)
 			goto out;
 		}
 
-		spec->lr.ctx_raw = str_buf;
+		spec->lr.ctx_raw.str = str_buf;
+		spec->lr.ctx_raw.len = entry_len -1;
 
-		if (strcmp(spec->lr.ctx_raw, "<<none>>") && rec->validating) {
+		if (rec->validating && strcmp(spec->lr.ctx_raw.str, "<<none>>")) {
 			if (selabel_validate(rec, &spec->lr) < 0) {
 				selinux_log(SELINUX_ERROR, "%s: context %s is invalid\n",
-						data->path, spec->lr.ctx_raw);
+						data->path, spec->lr.ctx_raw.str);
 				errno = EINVAL;
 				free(str_buf);
 				goto out;
@@ -492,14 +492,16 @@ static int read_binary_file(struct selabel_handle *rec)
 		if (err < 0 || !entry_len)
 			goto out;
 
-		spec->regex_str = (char *) map_area->next_addr;
+		spec->regex_str.str = (char *) map_area->next_addr;
 		err = next_entry(NULL, map_area, entry_len);
 		if (err < 0)
 			goto out;
 
-		if (spec->regex_str[entry_len - 1] != '\0')
+		if (spec->regex_str.str[entry_len - 1] != '\0')
 			goto out;
 
+		spec->regex_str.len = entry_len - 1;
+
 		/* Process mode */
 		if (version >= SELINUX_COMPILED_FCONTEXT_MODE)
 			err = next_entry(&mode, map_area, sizeof(mode));
@@ -715,11 +717,13 @@ static void closef(struct selabel_handle *rec)
 	for (i = 0; i < data->nspec; i++) {
 		spec = &data->spec_arr[i];
 		free(spec->lr.ctx_trans);
-		free(spec->lr.ctx_raw);
+		free(spec->lr.ctx_raw.str);
 		if (spec->from_mmap)
 			continue;
-		free(spec->regex_str);
-		free(spec->type_str);
+
+		free(spec->regex_str.str);
+		free(spec->type_str.str);
+
 		if (spec->regcomp) {
 			pcre_free(spec->regex);
 			pcre_free_study(spec->sd);
@@ -767,6 +771,11 @@ static struct spec *lookup_common(struct selabel_handle *rec,
 	const char *prev_slash, *next_slash;
 	unsigned int sofar = 0;
 
+	struct len_str none = {
+			.str = (char *)"<<none>>",
+			.len = 8
+	};
+
 	if (!data->nspec) {
 		errno = ENOENT;
 		goto finish;
@@ -834,7 +843,7 @@ static struct spec *lookup_common(struct selabel_handle *rec,
 		}
 	}
 
-	if (i < 0 || strcmp(spec_arr[i].lr.ctx_raw, "<<none>>") == 0) {
+	if (i < 0 || len_str_eq(&spec_arr[i].lr.ctx_raw, &none)) {
 		/* No matching specification. */
 		errno = ENOENT;
 		goto finish;
@@ -926,8 +935,8 @@ static enum selabel_cmp_result incomp(struct spec *spec1, struct spec *spec2, co
 	selinux_log(SELINUX_INFO,
 		    "selabel_cmp: mismatched %s on entry %d: (%s, %x, %s) vs entry %d: (%s, %x, %s)\n",
 		    reason,
-		    i, spec1->regex_str, spec1->mode, spec1->lr.ctx_raw,
-		    j, spec2->regex_str, spec2->mode, spec2->lr.ctx_raw);
+		    i, spec1->regex_str.str, spec1->mode, spec1->lr.ctx_raw.str,
+		    j, spec2->regex_str.str, spec2->mode, spec2->lr.ctx_raw.str);
 	return SELABEL_INCOMPARABLE;
 }
 
@@ -976,7 +985,7 @@ static enum selabel_cmp_result cmp(struct selabel_handle *h1,
 			    memcmp(spec1->regex, spec2->regex, len1))
 				return incomp(spec1, spec2, "regex", i, j);
 		} else {
-			if (strcmp(spec1->regex_str, spec2->regex_str))
+			if (strcmp(spec1->regex_str.str, spec2->regex_str.str))
 				return incomp(spec1, spec2, "regex_str", i, j);
 		}
 
@@ -995,7 +1004,7 @@ static enum selabel_cmp_result cmp(struct selabel_handle *h1,
 				return incomp(spec1, spec2, "stem", i, j);
 		}
 
-		if (strcmp(spec1->lr.ctx_raw, spec2->lr.ctx_raw))
+		if (!len_str_eq(&spec1->lr.ctx_raw, &spec2->lr.ctx_raw))
 			return incomp(spec1, spec2, "ctx_raw", i, j);
 
 		i++;
@@ -1020,17 +1029,17 @@ static void stats(struct selabel_handle *rec)
 
 	for (i = 0; i < nspec; i++) {
 		if (spec_arr[i].matches == 0) {
-			if (spec_arr[i].type_str) {
+			if (spec_arr[i].type_str.str) {
 				COMPAT_LOG(SELINUX_WARNING,
 				    "Warning!  No matches for (%s, %s, %s)\n",
-				    spec_arr[i].regex_str,
-				    spec_arr[i].type_str,
-				    spec_arr[i].lr.ctx_raw);
+				    spec_arr[i].regex_str.str,
+				    spec_arr[i].type_str.str,
+				    spec_arr[i].lr.ctx_raw.str);
 			} else {
 				COMPAT_LOG(SELINUX_WARNING,
 				    "Warning!  No matches for (%s, %s)\n",
-				    spec_arr[i].regex_str,
-				    spec_arr[i].lr.ctx_raw);
+				    spec_arr[i].regex_str.str,
+				    spec_arr[i].lr.ctx_raw.str);
 			}
 		}
 	}
diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
index da06164..cd021f4 100644
--- a/libselinux/src/label_file.h
+++ b/libselinux/src/label_file.h
@@ -26,10 +26,10 @@
 
 /* A file security context specification. */
 struct spec {
-	struct selabel_lookup_rec lr;	/* holds contexts for lookup result */
-	char *regex_str;	/* regular expession string for diagnostics */
-	char *type_str;		/* type string for diagnostic messages */
-	pcre *regex;		/* compiled regular expression */
+	struct selabel_lookup_rec lr; /* holds contexts for lookup result */
+	struct len_str regex_str;     /* regular expession string for diagnostics */
+	struct len_str type_str;     /* type string for diagnostic messages */
+	pcre *regex;                  /* compiled regular expression */
 	union {
 		pcre_extra *sd;	/* pointer to extra compiled stuff */
 		pcre_extra lsd;	/* used to hold the mmap'd version */
@@ -90,16 +90,19 @@ static inline pcre_extra *get_pcre_extra(struct spec *spec)
 		return spec->sd;
 }
 
-static inline mode_t string_to_mode(char *mode)
+static inline mode_t string_to_mode(struct len_str *mode)
 {
 	size_t len;
 
 	if (!mode)
 		return 0;
-	len = strlen(mode);
-	if (mode[0] != '-' || len != 2)
+
+	len = mode->len;
+
+	if (mode->str[0] != '-' || len != 2)
 		return -1;
-	switch (mode[1]) {
+
+	switch (mode->str[1]) {
 	case 'b':
 		return S_IFBLK;
 	case 'c':
@@ -153,8 +156,8 @@ static inline void spec_hasMetaChars(struct spec *spec)
 	int len;
 	char *end;
 
-	c = spec->regex_str;
-	len = strlen(spec->regex_str);
+	c = spec->regex_str.str;
+	len = spec->regex_str.len;
 	end = c + len;
 
 	spec->hasMetaChars = 0;
@@ -175,7 +178,7 @@ static inline void spec_hasMetaChars(struct spec *spec)
 		case '(':
 		case '{':
 			spec->hasMetaChars = 1;
-			spec->prefix_len = c - spec->regex_str;
+			spec->prefix_len = c - spec->regex_str.str;
 			return;
 		case '\\':	/* skip the next character */
 			c++;
@@ -327,13 +330,16 @@ static inline int compile_regex(struct saved_data *data, struct spec *spec,
 	if (spec->regcomp)
 		return 0; /* already done */
 
+	len = spec->regex_str.len;
+	reg_buf = spec->regex_str.str;
+
 	/* Skip the fixed stem. */
-	reg_buf = spec->regex_str;
-	if (spec->stem_id >= 0)
+	if (spec->stem_id >= 0) {
 		reg_buf += stem_arr[spec->stem_id].len;
+		len -= stem_arr[spec->stem_id].len;
+	}
 
 	/* Anchor the regular expression. */
-	len = strlen(reg_buf);
 	cp = anchored_regex = malloc(len + 3);
 	if (!anchored_regex)
 		return -1;
@@ -375,7 +381,15 @@ static inline int process_line(struct selabel_handle *rec,
 			char *line_buf, unsigned lineno)
 {
 	int items, len, rc;
-	char *regex = NULL, *type = NULL, *context = NULL;
+
+	struct len_str regex = { 0 } , type = { 0 }, context  = { 0 };
+
+	/* XXX Export this as a const */
+	struct len_str none = {
+			.str = (char *)"<<none>>",
+			.len = 8
+	};
+
 	struct saved_data *data = (struct saved_data *)rec->data;
 	struct spec *spec_arr;
 	unsigned int nspec = data->nspec;
@@ -399,21 +413,21 @@ static inline int process_line(struct selabel_handle *rec,
 			    "%s:  line %u is missing fields\n", path,
 			    lineno);
 		if (items == 1)
-			free(regex);
+			free(regex.str);
 		errno = EINVAL;
 		return -1;
 	} else if (items == 2) {
 		/* The type field is optional. */
 		context = type;
-		type = 0;
+		memset(&type, 0, sizeof(type));
 	}
 
-	len = get_stem_from_spec(regex);
-	if (len && prefix && strncmp(prefix, regex, len)) {
+	len = get_stem_from_spec(regex.str);
+	if (len && prefix && strncmp(prefix, regex.str, len)) {
 		/* Stem of regex does not match requested prefix, discard. */
-		free(regex);
-		free(type);
-		free(context);
+		free(regex.str);
+		free(type.str);
+		free(context.str);
 		return 0;
 	}
 
@@ -424,13 +438,13 @@ static inline int process_line(struct selabel_handle *rec,
 	spec_arr = data->spec_arr;
 
 	/* process and store the specification in spec. */
-	spec_arr[nspec].stem_id = find_stem_from_spec(data, regex);
-	spec_arr[nspec].regex_str = regex;
-
-	spec_arr[nspec].type_str = type;
+	spec_arr[nspec].stem_id = find_stem_from_spec(data, regex.str);
+	memcpy(&spec_arr[nspec].regex_str, &regex, sizeof(regex));
+	memcpy(&spec_arr[nspec].lr.ctx_raw, &context, sizeof(context));
 	spec_arr[nspec].mode = 0;
 
-	spec_arr[nspec].lr.ctx_raw = context;
+	if (type.str)
+		memcpy(&spec_arr[nspec].type_str, &type, sizeof(type));
 
 	/*
 	 * bump data->nspecs to cause closef() to cover it in its free
@@ -442,19 +456,19 @@ static inline int process_line(struct selabel_handle *rec,
 			    compile_regex(data, &spec_arr[nspec], &errbuf)) {
 		COMPAT_LOG(SELINUX_ERROR,
 			   "%s:  line %u has invalid regex %s:  %s\n",
-			   path, lineno, regex,
+			   path, lineno, regex.str,
 			   (errbuf ? errbuf : "out of memory"));
 		errno = EINVAL;
 		return -1;
 	}
 
-	if (type) {
-		mode_t mode = string_to_mode(type);
+	if (type.str) {
+		mode_t mode = string_to_mode(&type);
 
 		if (mode == (mode_t)-1) {
 			COMPAT_LOG(SELINUX_ERROR,
 				   "%s:  line %u has invalid file type %s\n",
-				   path, lineno, type);
+				   path, lineno, type.str);
 			errno = EINVAL;
 			return -1;
 		}
@@ -465,7 +479,7 @@ static inline int process_line(struct selabel_handle *rec,
 	 * any meta characters in the RE */
 	spec_hasMetaChars(&spec_arr[nspec]);
 
-	if (strcmp(context, "<<none>>") && rec->validating)
+	if (rec->validating && !len_str_eq(&context, &none))
 		compat_validate(rec, &spec_arr[nspec].lr, path, lineno);
 
 	return 0;
diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h
index aa48fff..51aa33d 100644
--- a/libselinux/src/label_internal.h
+++ b/libselinux/src/label_internal.h
@@ -71,8 +71,28 @@ extern struct selabel_sub *selabel_subs_init(const char *path,
 				    struct selabel_sub *list,
 				    struct selabel_digest *digest);
 
+/*
+ * A simple struct for tracking string lengths
+ * with strings.
+ */
+struct len_str {
+	size_t len;
+	char *str;
+};
+
+static inline bool len_str_eq(struct len_str *a, struct len_str *b)
+{
+	if (a->len != b->len)
+		return false;
+
+	if (a->str == b->str)
+		return true;
+
+	return !strcmp(a->str, b->str);
+}
+
 struct selabel_lookup_rec {
-	char * ctx_raw;
+	struct len_str ctx_raw;
 	char * ctx_trans;
 	int validated;
 };
diff --git a/libselinux/src/label_media.c b/libselinux/src/label_media.c
index 622741b..e85e973 100644
--- a/libselinux/src/label_media.c
+++ b/libselinux/src/label_media.c
@@ -56,7 +56,8 @@ static int process_line(const char *path, char *line_buf, int pass,
 
 	if (pass == 1) {
 		data->spec_arr[data->nspec].key = key;
-		data->spec_arr[data->nspec].lr.ctx_raw = context;
+		data->spec_arr[data->nspec].lr.ctx_raw.str = context;
+		data->spec_arr[data->nspec].lr.ctx_raw.len = strlen(context);
 	}
 
 	data->nspec++;
@@ -159,7 +160,7 @@ static void close(struct selabel_handle *rec)
 	for (i = 0; i < data->nspec; i++) {
 		spec = &spec_arr[i];
 		free(spec->key);
-		free(spec->lr.ctx_raw);
+		free(spec->lr.ctx_raw.str);
 		free(spec->lr.ctx_trans);
 	}
 
diff --git a/libselinux/src/label_support.c b/libselinux/src/label_support.c
index 26f9ef1..e9b842f 100644
--- a/libselinux/src/label_support.c
+++ b/libselinux/src/label_support.c
@@ -22,16 +22,17 @@
  *            errno will be set.
  *
  */
-static inline int read_spec_entry(char **entry, char **ptr, int *len, const char **errbuf)
+static inline int read_spec_entry(struct len_str *entry, char **ptr, const char **errbuf)
 {
-	*entry = NULL;
+	size_t len = 0;
 	char *tmp_buf = NULL;
 
+	memset(entry, 0, sizeof(*entry));
+
 	while (isspace(**ptr) && **ptr != '\0')
 		(*ptr)++;
 
 	tmp_buf = *ptr;
-	*len = 0;
 
 	while (!isspace(**ptr) && **ptr != '\0') {
 		if (!isascii(**ptr)) {
@@ -40,13 +41,15 @@ static inline int read_spec_entry(char **entry, char **ptr, int *len, const char
 			return -1;
 		}
 		(*ptr)++;
-		(*len)++;
+		len++;
 	}
 
-	if (*len) {
-		*entry = strndup(tmp_buf, *len);
-		if (!*entry)
+	if (len) {
+		entry->str = strndup(tmp_buf, len);
+		if (!entry->str)
 			return -1;
+
+		entry->len = len;
 	}
 
 	return 0;
@@ -56,7 +59,7 @@ static inline int read_spec_entry(char **entry, char **ptr, int *len, const char
  * line_buf - Buffer containing the spec entries .
  * errbuf   - Double pointer used for passing back specific error messages.
  * num_args - The number of spec parameter entries to process.
- * ...      - A 'char **spec_entry' for each parameter.
+ * ...      - A 'struct len_str **spec_entry' for each parameter.
  * returns  - The number of items processed. On error, it returns -1 with errno
  *            set and may set errbuf to a specific error message.
  *
@@ -65,8 +68,9 @@ static inline int read_spec_entry(char **entry, char **ptr, int *len, const char
  */
 int hidden read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...)
 {
-	char **spec_entry, *buf_p;
-	int len, rc, items, entry_len = 0;
+	struct len_str *spec_entry;
+	char *buf_p;
+	int len, rc, items;
 	va_list ap;
 
 	*errbuf = NULL;
@@ -93,20 +97,22 @@ int hidden read_spec_entries(char *line_buf, const char **errbuf, int num_args,
 
 	items = 0;
 	while (items < num_args) {
-		spec_entry = va_arg(ap, char **);
+		spec_entry = va_arg(ap, struct len_str *);
 
 		if (len - 1 == buf_p - line_buf) {
 			va_end(ap);
 			return items;
 		}
 
-		rc = read_spec_entry(spec_entry, &buf_p, &entry_len, errbuf);
+		rc = read_spec_entry(spec_entry, &buf_p, errbuf);
 		if (rc < 0) {
 			va_end(ap);
 			return rc;
 		}
-		if (entry_len)
+
+		if (spec_entry->len) {
 			items++;
+		}
 	}
 	va_end(ap);
 	return items;
diff --git a/libselinux/src/label_x.c b/libselinux/src/label_x.c
index 700def1..cdbac8c 100644
--- a/libselinux/src/label_x.c
+++ b/libselinux/src/label_x.c
@@ -81,7 +81,8 @@ static int process_line(const char *path, char *line_buf, int pass,
 			return 0;
 		}
 		data->spec_arr[data->nspec].key = key;
-		data->spec_arr[data->nspec].lr.ctx_raw = context;
+		data->spec_arr[data->nspec].lr.ctx_raw.str = context;
+		data->spec_arr[data->nspec].lr.ctx_raw.len = strlen(context);
 		free(type);
 	}
 
@@ -186,7 +187,7 @@ static void close(struct selabel_handle *rec)
 	for (i = 0; i < data->nspec; i++) {
 		spec = &spec_arr[i];
 		free(spec->key);
-		free(spec->lr.ctx_raw);
+		free(spec->lr.ctx_raw.str);
 		free(spec->lr.ctx_trans);
 	}
 
diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c
index 4764ab7..96c39b4 100644
--- a/libselinux/src/matchpathcon.c
+++ b/libselinux/src/matchpathcon.c
@@ -541,7 +541,7 @@ int compat_validate(struct selabel_handle *rec,
 		    const char *path, unsigned lineno)
 {
 	int rc;
-	char **ctx = &contexts->ctx_raw;
+	char **ctx = &contexts->ctx_raw.str;
 
 	if (myinvalidcon)
 		rc = myinvalidcon(path, lineno, *ctx);
