From 256d5512e6ef05526d8d7bd46e9d58eeb24fddc0 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Mon, 8 Sep 2014 09:28:25 +0000 Subject: [PATCH] [msan] Fix wrong array index in io_submit interceptor. llvm-svn: 217362 --- .../sanitizer_common_syscalls.inc | 8 +++---- compiler-rt/test/msan/Linux/syscalls.cc | 22 +++++++++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc index 23da70303f9f..a52338b62f5e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -1326,13 +1326,13 @@ PRE_SYSCALL(io_submit)(long ctx_id, long nr, __sanitizer_iocb **iocbpp) { } else if (op == iocb_cmd_pread && buf && len) { POST_WRITE(buf, len); } else if (op == iocb_cmd_pwritev) { - __sanitizer_iovec *iovec = (__sanitizer_iovec*)iocbpp[i]->aio_buf; + __sanitizer_iovec *iovec = (__sanitizer_iovec*)buf; for (uptr v = 0; v < len; v++) - PRE_READ(iovec[i].iov_base, iovec[i].iov_len); + PRE_READ(iovec[v].iov_base, iovec[v].iov_len); } else if (op == iocb_cmd_preadv) { - __sanitizer_iovec *iovec = (__sanitizer_iovec*)iocbpp[i]->aio_buf; + __sanitizer_iovec *iovec = (__sanitizer_iovec*)buf; for (uptr v = 0; v < len; v++) - POST_WRITE(iovec[i].iov_base, iovec[i].iov_len); + POST_WRITE(iovec[v].iov_base, iovec[v].iov_len); } // See comment in io_getevents. COMMON_SYSCALL_RELEASE(data); diff --git a/compiler-rt/test/msan/Linux/syscalls.cc b/compiler-rt/test/msan/Linux/syscalls.cc index 39b893b8e13a..4dd97e745148 100644 --- a/compiler-rt/test/msan/Linux/syscalls.cc +++ b/compiler-rt/test/msan/Linux/syscalls.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -84,17 +85,24 @@ int main(int argc, char *argv[]) { assert(__msan_test_shadow(buf, sizeof(buf)) == sizeof(void *)); __msan_poison(buf, sizeof(buf)); - struct iocb iocb[2]; - struct iocb *iocbp[2] = { &iocb[0], &iocb[1] }; + struct iocb iocb[3]; + struct iocb *iocbp[3] = { &iocb[0], &iocb[1], &iocb[2] }; memset(iocb, 0, sizeof(iocb)); iocb[0].aio_lio_opcode = IOCB_CMD_PREAD; iocb[0].aio_buf = (__u64)buf; - iocb[0].aio_nbytes = kFortyTwo; + iocb[0].aio_nbytes = 10; iocb[1].aio_lio_opcode = IOCB_CMD_PREAD; - iocb[1].aio_buf = (__u64)(&buf[kFortyTwo]); - iocb[1].aio_nbytes = kFortyTwo; - __sanitizer_syscall_pre_io_submit(0, 2, &iocbp); - assert(__msan_test_shadow(buf, sizeof(buf)) == 2 * kFortyTwo); + iocb[1].aio_buf = (__u64)(&buf[20]); + iocb[1].aio_nbytes = 15; + struct iovec vec[2] = { {&buf[40], 3}, {&buf[50], 20} }; + iocb[2].aio_lio_opcode = IOCB_CMD_PREADV; + iocb[2].aio_buf = (__u64)(&vec); + iocb[2].aio_nbytes = 2; + __sanitizer_syscall_pre_io_submit(0, 3, &iocbp); + assert(__msan_test_shadow(buf, sizeof(buf)) == 10); + assert(__msan_test_shadow(buf + 20, sizeof(buf) - 20) == 15); + assert(__msan_test_shadow(buf + 40, sizeof(buf) - 40) == 3); + assert(__msan_test_shadow(buf + 50, sizeof(buf) - 50) == 20); __msan_poison(buf, sizeof(buf)); char *p = buf;