summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Antipov <dmitry.antipov@linaro.org>2012-12-12 16:56:45 +0400
committerDmitry Antipov <dmitry.antipov@linaro.org>2012-12-12 16:56:45 +0400
commit2b9fc2cd8ef210207b3bee3f068a2608d0a6611b (patch)
tree7ef2b76327629c54c465ac6d25e114de77fd0753
parent750254965aa57dbf7b9aeba20895b641cdc2ad25 (diff)
downloadlinaro-android-kernel-test-2b9fc2cd8ef210207b3bee3f068a2608d0a6611b.tar.gz
Add test cases for ASHMEM_GET_PROT_MASK and ASHMEM_SET_PROT_MASK ioctls.
-rw-r--r--ashmemtest-basic/ashmemtest.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/ashmemtest-basic/ashmemtest.c b/ashmemtest-basic/ashmemtest.c
index eb83986..23d83d1 100644
--- a/ashmemtest-basic/ashmemtest.c
+++ b/ashmemtest-basic/ashmemtest.c
@@ -394,6 +394,93 @@ void ashmem_mmap (char *ashmemdev, size_t pagesize)
printf ("%d [%s]: test passed\n", testno, __func__);
}
+/* Stolen from the kernel */
+#define DEFAULT_PROT_MASK (PROT_READ | PROT_WRITE | PROT_EXEC)
+
+void ashmem_prot (char *ashmemdev, size_t pagesize)
+{
+ void *mem;
+ int fd, ret;
+
+ testno++;
+
+ /* check whether default protection is read/write/exec */
+ fd = test_open (ashmemdev, O_RDWR);
+ ret = ioctl (fd, ASHMEM_SET_SIZE, pagesize);
+ if (ret < 0)
+ fatal (errno, "can't allocate %ld-bytes read-only region");
+ ret = ioctl (fd, ASHMEM_GET_PROT_MASK);
+ if (ret != DEFAULT_PROT_MASK)
+ fatal (0, "default protection mask mismatch (got %x expect %x)",
+ ret, DEFAULT_PROT_MASK);
+ test_close (fd);
+
+ /* check whether we can remove some protection bits */
+ fd = test_open (ashmemdev, O_RDWR);
+ ret = ioctl (fd, ASHMEM_SET_SIZE, pagesize);
+ if (ret < 0)
+ fatal (errno, "can't allocate %ld-bytes read-only region");
+ ret = ioctl (fd, ASHMEM_GET_PROT_MASK);
+ if (ret != DEFAULT_PROT_MASK)
+ fatal (errno, "can't get protection mask or unexpected mask");
+ ret &= ~(PROT_READ | PROT_WRITE);
+ ret = ioctl (fd, ASHMEM_SET_PROT_MASK, ret);
+ if (ret < 0)
+ fatal (errno, "can't remove protection bits");
+ ret = ioctl (fd, ASHMEM_GET_PROT_MASK);
+ if (ret != PROT_EXEC)
+ fatal (errno, "protection mask mismatch (expect %x got %x)", PROT_EXEC, ret);
+ test_close (fd);
+
+ /* check whether we can't map read/write after removing PROT_READ... */
+ fd = test_open (ashmemdev, O_RDWR);
+ ret = ioctl (fd, ASHMEM_SET_SIZE, pagesize);
+ if (ret < 0)
+ fatal (errno, "can't allocate %ld-bytes read-only region");
+ ret = ioctl (fd, ASHMEM_GET_PROT_MASK);
+ if (ret != DEFAULT_PROT_MASK)
+ fatal (errno, "can't get protection mask or unexpected mask");
+ ret &= ~PROT_READ;
+ ret = ioctl (fd, ASHMEM_SET_PROT_MASK, ret);
+ if (ret < 0)
+ fatal (errno, "can't remove protection bits");
+ mem = mmap (NULL, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (mem != MAP_FAILED || errno != EPERM)
+ fatal (errno, "should not allow read/write map after removing PROT_READ");
+ /* ...but can map write-only */
+ mem = mmap (NULL, pagesize, PROT_WRITE, MAP_SHARED, fd, 0);
+ if (mem == MAP_FAILED)
+ fatal (errno, "should allow write-only map after removing PROT_READ");
+ if (munmap (mem, pagesize))
+ fatal (errno, "can't unmap ashmem region");
+ test_close (fd);
+
+ /* likewise after removing PROT_WRITE... */
+ fd = test_open (ashmemdev, O_RDWR);
+ ret = ioctl (fd, ASHMEM_SET_SIZE, pagesize);
+ if (ret < 0)
+ fatal (errno, "can't allocate %ld-bytes read-only region");
+ ret = ioctl (fd, ASHMEM_GET_PROT_MASK);
+ if (ret != DEFAULT_PROT_MASK)
+ fatal (errno, "can't get protection mask or unexpected mask");
+ ret &= ~PROT_WRITE;
+ ret = ioctl (fd, ASHMEM_SET_PROT_MASK, ret);
+ if (ret < 0)
+ fatal (errno, "can't remove protection bits");
+ mem = mmap (NULL, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (mem != MAP_FAILED || errno != EPERM)
+ fatal (errno, "should not allow read/write map after removing PROT_WRITE");
+ /* ...still can map read-only */
+ mem = mmap (NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0);
+ if (mem == MAP_FAILED)
+ fatal (errno, "should allow read-only map after removing PROT_WRITE");
+ if (munmap (mem, pagesize))
+ fatal (errno, "can't unmap ashmem region");
+ test_close (fd);
+
+ printf ("%d [%s]: test passed\n", testno, __func__);
+}
+
int main(int argc, char *argv[])
{
char ashmemdev[64];
@@ -407,5 +494,6 @@ int main(int argc, char *argv[])
ashmem_pin_status (ashmemdev, pagesize);
ashmem_size (ashmemdev, pagesize);
ashmem_mmap (ashmemdev, pagesize);
+ ashmem_prot (ashmemdev, pagesize);
return 0;
}