rootdev: Don't try to access /dev/block.

When the device used to back a path is found in /sys/block, rootdev will
double check that /dev/block/<device name> exists and that the dev_t
matches the one in /sys/block/.
On Android, the manufacturer can add an SELinux context for that device
node which will prevent core daemons from accessing it, failing the call
to rootdev.

To avoid this, rootdev should return the device node path without trying
to access it.

This CL also enable building with Clang to ensure we use the strictest
compiler possible.

BUG: 24143423
BUG: 24267261
TEST: metricsd starts and find the main disk without any SELinux denial.
TEST: builds with clang and -Werror.

Change-Id: Icfe64695c28277d4c8eb9c89de1e13a767a703b8
diff --git a/Android.mk b/Android.mk
index 613fa85..6878e8a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,6 +23,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := librootdev
 LOCAL_CFLAGS += $(rootdev_CFLAGS)
+LOCAL_CLANG := true
 LOCAL_CPPFLAGS += $(rootdev_CPPFLAGS)
 LOCAL_SRC_FILES := rootdev.c
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
@@ -32,6 +33,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := rootdev
 LOCAL_CFLAGS += $(rootdev_CFLAGS)
+LOCAL_CLANG := true
 LOCAL_CPPFLAGS += $(rootdev_CPPFLAGS)
 LOCAL_SHARED_LIBRARIES := librootdev
 LOCAL_SRC_FILES := main.c
diff --git a/rootdev.c b/rootdev.c
index f0de1ff..e4c6d55 100644
--- a/rootdev.c
+++ b/rootdev.c
@@ -343,9 +343,8 @@
 }
 
 int rootdev_get_path(char *path, size_t size, const char *device,
-                     dev_t dev, const char *dev_path) {
+                     const char *dev_path) {
   int path_len;
-  struct stat dev_statbuf;
 
   if (!dev_path)
     dev_path = kDefaultDevPath;
@@ -357,11 +356,10 @@
   if (path_len != strlen(dev_path) + 1 + strlen(device))
     return -1;
 
-  if (stat(path, &dev_statbuf) != 0)
-    return 1;
-
-  if (dev && dev != dev_statbuf.st_rdev)
-    return 2;
+  // TODO(bsimonnet): We should check that |path| exists and is the right
+  // device. We don't do this currently as OEMs can add custom SELinux rules
+  // which may prevent us from accessing this.
+  // See b/24267261.
 
   return 0;
 }
@@ -397,7 +395,7 @@
     rootdev_strip_partition(devname, size);
   }
 
-  res = rootdev_get_path(path, size, devname, *dev, dev_path);
+  res = rootdev_get_path(path, size, devname, dev_path);
 
   return res;
 }
diff --git a/rootdev.h b/rootdev.h
index 74a48da..aacfaf0 100644
--- a/rootdev.h
+++ b/rootdev.h
@@ -71,7 +71,6 @@
  * @path: char array to store the path
  * @size: size of @devpath
  * @device: name of the device
- * @dev: optional expected dev_t of the node.
  * @dev_path: path to dev tree. NULL for default (/dev)
  *
  * A @dev of 0 is ignored.
@@ -79,16 +78,14 @@
  * @path is populated for all return codes.
  * Returns 0 on success and non-zero on error:
  * -1 on unexpected errors (@path may be invalid)
- *  1 on no existing @path
- *  2 @path exists but the dev_t value is mismatched.
  *
  * Nb, this function does NOT search /dev for a match.  It performs a normal
- *     string concatenation and probes for the existence.  If udev has moved,
- *     or otherwise renamed, the device, a positive value is returned.
- *     The caller may then use the dev_t and @path to create the node with
- *     mknod(2).
+ *     string concatenation.
+ *     We can't check if the device actually exists as vendors may create an
+ *     SELinux context we don't know about for it (in which case, this function
+ *     would always fail).
  */
-int rootdev_get_path(char *path, size_t size, const char *device, dev_t dev,
+int rootdev_get_path(char *path, size_t size, const char *device,
                      const char *dev_path);
 
 const char *rootdev_get_partition(const char *dst, size_t len);