diff options
author | Dmitry Antipov <dmitry.antipov@linaro.org> | 2012-12-12 16:56:45 +0400 |
---|---|---|
committer | Dmitry Antipov <dmitry.antipov@linaro.org> | 2012-12-12 16:56:45 +0400 |
commit | 2b9fc2cd8ef210207b3bee3f068a2608d0a6611b (patch) | |
tree | 7ef2b76327629c54c465ac6d25e114de77fd0753 | |
parent | 750254965aa57dbf7b9aeba20895b641cdc2ad25 (diff) | |
download | linaro-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.c | 88 |
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; } |