libselinux: fail hard on invalid file_contexts entries

Fail hard on any error during file_contexts processing.
We want to catch any such errors early and not proceed
with a potentially mislabeled system.  This was the original
logic but was loosened long ago to more gracefully handle
user error in Linux distributions (a single typo could lead
to not being able to label anything, even if the relevant
entry for the files in question was correct).  However,
in Android, file_contexts is not modified at runtime and
we want to fully validate it at build, so we want to fail
hard in these cases, and in modern Linux, file_contexts is
modified using tools (semanage, semodule) and a library
(libsemanage) that should already be fully validating values
before adding entries, and that trigger a setfiles -c validation
(equivalent to Android checkfc) before committing the transaction.

Change-Id: If98dc462b7132c34d5a1ae0a2634fda3779227c3
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
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;
 		}
 	}