libcutils: ashmem print error message for invalid fd

NB: We decided to not sniff for the constant saved __ashmem_rdev in
the early error path; requiring either the use of atomic operations,
or acquiring a lock to do it correctly. The heroics are not worth it.

Bug: 26871259
Change-Id: I46249838850ae32063eb5b7d08c731c5bb0fbf6b
diff --git a/libcutils/ashmem-dev.c b/libcutils/ashmem-dev.c
index 77e4d0d..d6a48c9 100644
--- a/libcutils/ashmem-dev.c
+++ b/libcutils/ashmem-dev.c
@@ -19,6 +19,7 @@
  * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
  * used by the simulator.
  */
+#define LOG_TAG "ashmem"
 
 #include <errno.h>
 #include <fcntl.h>
@@ -32,6 +33,7 @@
 #include <linux/ashmem.h>
 
 #include <cutils/ashmem.h>
+#include <log/log.h>
 
 #define ASHMEM_DEVICE "/dev/ashmem"
 
@@ -92,6 +94,7 @@
         return -1;
     }
 
+    rdev = 0; /* Too much complexity to sniff __ashmem_rdev */
     if (S_ISCHR(st.st_mode) && st.st_rdev) {
         pthread_mutex_lock(&__ashmem_lock);
         rdev = __ashmem_rdev;
@@ -114,6 +117,17 @@
         }
     }
 
+    if (rdev) {
+        ALOGE("illegal fd=%d mode=0%o rdev=%d:%d expected 0%o %d:%d",
+          fd, st.st_mode, major(st.st_rdev), minor(st.st_rdev),
+          S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IRGRP,
+          major(rdev), minor(rdev));
+    } else {
+        ALOGE("illegal fd=%d mode=0%o rdev=%d:%d expected 0%o",
+          fd, st.st_mode, major(st.st_rdev), minor(st.st_rdev),
+          S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IRGRP);
+    }
+
     errno = ENOTTY;
     return -1;
 }