Merge changes from topic 'file_contexts.bin'

* changes:
  libselinux: support context validation on file_contexts.bin
  libselinux: test for file_contexts.bin format
  libselinux: add selabel_cmp interface and label_file backend
  libselinux: switch to file_contexts.bin
  libselinux: support specifying file_contexts.bin file path
  libselinux: support file_contexts.bin without file_contexts
diff --git a/src/label_android_property.c b/src/label_android_property.c
index 4af9896..af06c4a 100644
--- a/src/label_android_property.c
+++ b/src/label_android_property.c
@@ -94,11 +94,12 @@
 	if (items <= 0)
 		return items;
 	if (items != 2) {
-		selinux_log(SELINUX_WARNING,
-			    "%s:  line %u is missing fields, skipping\n", path,
+		selinux_log(SELINUX_ERROR,
+			    "%s:  line %u is missing fields\n", path,
 			    lineno);
 		free(prop);
-		return 0;
+		errno = EINVAL;
+		return -1;
 	}
 
 	if (pass == 0) {
@@ -107,26 +108,15 @@
 	} else if (pass == 1) {
 		/* On the second pass, process and store the specification in spec. */
 		spec_arr[nspec].property_key = prop;
-		if (!spec_arr[nspec].property_key) {
-			selinux_log(SELINUX_WARNING,
-				    "%s:  out of memory at line %u on prop %s\n",
-				    path, lineno, prop);
-			return -1;
-		}
-
 		spec_arr[nspec].lr.ctx_raw = context;
-		if (!spec_arr[nspec].lr.ctx_raw) {
-			selinux_log(SELINUX_WARNING,
-				    "%s:  out of memory at line %u on context %s\n",
-				    path, lineno, context);
-			return -1;
-		}
 
 		if (rec->validating) {
 			if (selabel_validate(rec, &spec_arr[nspec].lr) < 0) {
-				selinux_log(SELINUX_WARNING,
+				selinux_log(SELINUX_ERROR,
 					    "%s:  line %u has invalid context %s\n",
 					    path, lineno, spec_arr[nspec].lr.ctx_raw);
+				errno = EINVAL;
+				return -1;
 			}
 		}
 	}
diff --git a/src/label_file.h b/src/label_file.h
index 3f19394..678f07c 100644
--- a/src/label_file.h
+++ b/src/label_file.h
@@ -392,12 +392,13 @@
 		return items;
 
 	if (items < 2) {
-		selinux_log(SELINUX_WARNING,
-			    "%s:  line %u is missing fields, skipping\n", path,
+		selinux_log(SELINUX_ERROR,
+			    "%s:  line %u is missing fields\n", path,
 			    lineno);
 		if (items == 1)
 			free(regex);
-		return 0;
+		errno = EINVAL;
+		return -1;
 	} else if (items == 2) {
 		/* The type field is optional. */
 		context = type;
@@ -424,10 +425,12 @@
 	spec_arr[nspec].regex_str = regex;
 	if (rec->validating &&
 			    compile_regex(data, &spec_arr[nspec], &errbuf)) {
-		selinux_log(SELINUX_WARNING,
+		selinux_log(SELINUX_ERROR,
 			   "%s:  line %u has invalid regex %s:  %s\n",
 			   path, lineno, regex,
 			   (errbuf ? errbuf : "out of memory"));
+		errno = EINVAL;
+		return -1;
 	}
 
 	/* Convert the type string to a mode format */
@@ -437,10 +440,11 @@
 		mode_t mode = string_to_mode(type);
 
 		if (mode == (mode_t)-1) {
-			selinux_log(SELINUX_WARNING,
+			selinux_log(SELINUX_ERROR,
 				   "%s:  line %u has invalid file type %s\n",
 				   path, lineno, type);
-			mode = 0;
+			errno = EINVAL;
+			return -1;
 		}
 		spec_arr[nspec].mode = mode;
 	}
@@ -453,9 +457,11 @@
 
 	if (strcmp(context, "<<none>>") && rec->validating) {
 		if (selabel_validate(rec, &spec_arr[nspec].lr) < 0) {
-			selinux_log(SELINUX_WARNING,
+			selinux_log(SELINUX_ERROR,
 				    "%s:  line %u has invalid context %s\n",
 				    path, lineno, spec_arr[nspec].lr.ctx_raw);
+			errno = EINVAL;
+			return -1;
 		}
 	}