libselinux: support file_contexts.bin without file_contexts

Change the label_file backend in libselinux to support systems
that only have file_contexts.bin files installed and do not ship
a file_contexts file at all.  Only fail if neither file can be
loaded.

Change-Id: I15660f4b3e4c5cb8ae0ec1498c74d6fcbb9a0400
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
diff --git a/src/label_file.c b/src/label_file.c
index 54931d7..af73717 100644
--- a/src/label_file.c
+++ b/src/label_file.c
@@ -417,20 +417,30 @@
 	}
 
 	/* Open the specification file. */
-	if ((fp = fopen(path, "r")) == NULL)
-		return -1;
-
-	if (fstat(fileno(fp), &sb) < 0)
-		return -1;
-	if (!S_ISREG(sb.st_mode)) {
-		errno = EINVAL;
-		return -1;
+	fp = fopen(path, "r");
+	if (fp) {
+		if (fstat(fileno(fp), &sb) < 0)
+			return -1;
+		if (!S_ISREG(sb.st_mode)) {
+			errno = EINVAL;
+			return -1;
+		}
+	} else {
+		/*
+		 * Text file does not exist, so clear the timestamp
+		 * so that we will always pass the timestamp comparison
+		 * with the bin file in load_mmap().
+		 */
+		sb.st_mtime = 0;
 	}
 
 	rc = load_mmap(rec, path, &sb);
 	if (rc == 0)
 		goto out;
 
+	if (!fp)
+		return -1; /* no text or bin file */
+
 	/*
 	 * Then do detailed validation of the input and fill the spec array
 	 */
@@ -444,7 +454,8 @@
 
 out:
 	free(line_buf);
-	fclose(fp);
+	if (fp)
+		fclose(fp);
 	return rc;
 }