1 /* SPDX-License-Identifier: MIT */ 2 3 #include "liburing/sanitize.h" 4 5 #include <sanitizer/asan_interface.h> 6 #include <stdlib.h> 7 #include "liburing.h" 8 sanitize_sqe_addr(struct io_uring_sqe * sqe)9static inline void sanitize_sqe_addr(struct io_uring_sqe *sqe) 10 { 11 if (__asan_address_is_poisoned((void *) (unsigned long) sqe->addr) != 0) { 12 __asan_describe_address((void *) (unsigned long) sqe->addr); 13 exit(1); 14 } 15 } sanitize_sqe_optval(struct io_uring_sqe * sqe)16static inline void sanitize_sqe_optval(struct io_uring_sqe *sqe) 17 { 18 if (__asan_region_is_poisoned((void *) (unsigned long) sqe->optval, sqe->optlen) != 0) { 19 __asan_describe_address((void *) (unsigned long) sqe->optval); 20 exit(1); 21 } 22 } sanitize_sqe_addr2(struct io_uring_sqe * sqe)23static inline void sanitize_sqe_addr2(struct io_uring_sqe *sqe) 24 { 25 if (__asan_address_is_poisoned((void *) (unsigned long) sqe->addr2) != 0) { 26 __asan_describe_address((void *) (unsigned long) sqe->addr2); 27 exit(1); 28 } 29 } sanitize_sqe_addr3(struct io_uring_sqe * sqe)30static inline void sanitize_sqe_addr3(struct io_uring_sqe *sqe) 31 { 32 if (__asan_address_is_poisoned((void *) (unsigned long) sqe->addr3) != 0) { 33 __asan_describe_address((void *) (unsigned long) sqe->addr3); 34 exit(1); 35 } 36 } sanitize_sqe_addr_and_add2(struct io_uring_sqe * sqe)37static inline void sanitize_sqe_addr_and_add2(struct io_uring_sqe *sqe) 38 { 39 sanitize_sqe_addr(sqe); 40 sanitize_sqe_addr2(sqe); 41 } sanitize_sqe_addr_and_add3(struct io_uring_sqe * sqe)42static inline void sanitize_sqe_addr_and_add3(struct io_uring_sqe *sqe) 43 { 44 sanitize_sqe_addr(sqe); 45 sanitize_sqe_addr3(sqe); 46 } sanitize_sqe_nop(struct io_uring_sqe * sqe)47static inline void sanitize_sqe_nop(struct io_uring_sqe *sqe) 48 { 49 } 50 51 typedef void (*sanitize_sqe_handler)(struct io_uring_sqe *sqe); 52 sanitize_sqe_handler sanitize_handlers[IORING_OP_LAST]; 53 bool sanitize_handlers_initialized = false; 54 initialize_sanitize_handlers()55static inline void initialize_sanitize_handlers() 56 { 57 if (sanitize_handlers_initialized) 58 return; 59 60 sanitize_handlers[IORING_OP_NOP] = sanitize_sqe_nop; 61 sanitize_handlers[IORING_OP_READV] = sanitize_sqe_addr; 62 sanitize_handlers[IORING_OP_WRITEV] = sanitize_sqe_addr; 63 sanitize_handlers[IORING_OP_FSYNC] = sanitize_sqe_addr; 64 sanitize_handlers[IORING_OP_READ_FIXED] = sanitize_sqe_addr; 65 sanitize_handlers[IORING_OP_WRITE_FIXED] = sanitize_sqe_addr; 66 sanitize_handlers[IORING_OP_POLL_ADD] = sanitize_sqe_addr; 67 sanitize_handlers[IORING_OP_POLL_REMOVE] = sanitize_sqe_nop; 68 sanitize_handlers[IORING_OP_SYNC_FILE_RANGE] = sanitize_sqe_addr; 69 sanitize_handlers[IORING_OP_SENDMSG] = sanitize_sqe_addr; 70 sanitize_handlers[IORING_OP_RECVMSG] = sanitize_sqe_addr; 71 sanitize_handlers[IORING_OP_TIMEOUT] = sanitize_sqe_addr; 72 sanitize_handlers[IORING_OP_TIMEOUT_REMOVE] = sanitize_sqe_nop; 73 sanitize_handlers[IORING_OP_ACCEPT] = sanitize_sqe_addr; 74 sanitize_handlers[IORING_OP_ASYNC_CANCEL] = sanitize_sqe_nop; 75 sanitize_handlers[IORING_OP_LINK_TIMEOUT] = sanitize_sqe_addr; 76 sanitize_handlers[IORING_OP_CONNECT] = sanitize_sqe_addr; 77 sanitize_handlers[IORING_OP_FALLOCATE] = sanitize_sqe_nop; 78 sanitize_handlers[IORING_OP_OPENAT] = sanitize_sqe_addr; 79 sanitize_handlers[IORING_OP_CLOSE] = sanitize_sqe_addr; 80 sanitize_handlers[IORING_OP_FILES_UPDATE] = sanitize_sqe_addr; 81 sanitize_handlers[IORING_OP_STATX] = sanitize_sqe_addr; 82 sanitize_handlers[IORING_OP_READ] = sanitize_sqe_addr; 83 sanitize_handlers[IORING_OP_WRITE] = sanitize_sqe_addr; 84 sanitize_handlers[IORING_OP_FADVISE] = sanitize_sqe_nop; 85 sanitize_handlers[IORING_OP_MADVISE] = sanitize_sqe_addr; 86 sanitize_handlers[IORING_OP_SEND] = sanitize_sqe_addr_and_add2; 87 sanitize_handlers[IORING_OP_RECV] = sanitize_sqe_addr; 88 sanitize_handlers[IORING_OP_OPENAT2] = sanitize_sqe_addr; 89 sanitize_handlers[IORING_OP_EPOLL_CTL] = sanitize_sqe_addr; 90 sanitize_handlers[IORING_OP_SPLICE] = sanitize_sqe_nop; 91 sanitize_handlers[IORING_OP_PROVIDE_BUFFERS] = sanitize_sqe_addr; 92 sanitize_handlers[IORING_OP_REMOVE_BUFFERS] = sanitize_sqe_addr; 93 sanitize_handlers[IORING_OP_TEE] = sanitize_sqe_nop; 94 sanitize_handlers[IORING_OP_SHUTDOWN] = sanitize_sqe_addr; 95 sanitize_handlers[IORING_OP_RENAMEAT] = sanitize_sqe_addr; 96 sanitize_handlers[IORING_OP_UNLINKAT] = sanitize_sqe_addr; 97 sanitize_handlers[IORING_OP_MKDIRAT] = sanitize_sqe_addr; 98 sanitize_handlers[IORING_OP_SYMLINKAT] = sanitize_sqe_addr; 99 sanitize_handlers[IORING_OP_LINKAT] = sanitize_sqe_addr; 100 sanitize_handlers[IORING_OP_MSG_RING] = sanitize_sqe_addr_and_add3; 101 sanitize_handlers[IORING_OP_FSETXATTR] = sanitize_sqe_addr; 102 sanitize_handlers[IORING_OP_SETXATTR] = sanitize_sqe_addr_and_add3; 103 sanitize_handlers[IORING_OP_FGETXATTR] = sanitize_sqe_addr; 104 sanitize_handlers[IORING_OP_GETXATTR] = sanitize_sqe_addr_and_add3; 105 sanitize_handlers[IORING_OP_SOCKET] = sanitize_sqe_addr; 106 sanitize_handlers[IORING_OP_URING_CMD] = sanitize_sqe_optval; 107 sanitize_handlers[IORING_OP_SEND_ZC] = sanitize_sqe_addr; 108 sanitize_handlers[IORING_OP_SENDMSG_ZC] = sanitize_sqe_addr; 109 sanitize_handlers[IORING_OP_READ_MULTISHOT] = sanitize_sqe_addr; 110 sanitize_handlers[IORING_OP_WAITID] = sanitize_sqe_addr_and_add2; 111 sanitize_handlers[IORING_OP_FUTEX_WAIT] = sanitize_sqe_addr; 112 sanitize_handlers[IORING_OP_FUTEX_WAKE] = sanitize_sqe_addr; 113 sanitize_handlers[IORING_OP_FUTEX_WAITV] = sanitize_sqe_addr; 114 sanitize_handlers[IORING_OP_FIXED_FD_INSTALL] = sanitize_sqe_addr; 115 sanitize_handlers[IORING_OP_FTRUNCATE] = sanitize_sqe_addr; 116 sanitize_handlers[IORING_OP_BIND] = sanitize_sqe_addr; 117 sanitize_handlers[IORING_OP_LISTEN] = sanitize_sqe_addr; 118 sanitize_handlers_initialized = true; 119 } 120 liburing_sanitize_ring(struct io_uring * ring)121void liburing_sanitize_ring(struct io_uring *ring) 122 { 123 struct io_uring_sq *sq = &ring->sq; 124 struct io_uring_sqe *sqe; 125 unsigned int head; 126 int shift = 0; 127 128 initialize_sanitize_handlers(); 129 130 if (ring->flags & IORING_SETUP_SQE128) 131 shift = 1; 132 if (!(ring->flags & IORING_SETUP_SQPOLL)) 133 head = *sq->khead; 134 else 135 head = io_uring_smp_load_acquire(sq->khead); 136 137 while (head != sq->sqe_tail) { 138 sqe = &sq->sqes[(head & sq->ring_mask) << shift]; 139 if (sqe->opcode < IORING_OP_LAST) 140 sanitize_handlers[sqe->opcode](sqe); 141 head++; 142 } 143 } 144 liburing_sanitize_address(const void * addr)145void liburing_sanitize_address(const void *addr) 146 { 147 if (__asan_address_is_poisoned(addr) != 0) { 148 __asan_describe_address((void *)addr); 149 exit(1); 150 } 151 } 152 liburing_sanitize_region(const void * addr,unsigned int len)153void liburing_sanitize_region(const void *addr, unsigned int len) 154 { 155 if (__asan_region_is_poisoned((void *)addr, len) != 0) { 156 __asan_describe_address((void *)addr); 157 exit(1); 158 } 159 } 160 liburing_sanitize_iovecs(const struct iovec * iovecs,unsigned nr)161void liburing_sanitize_iovecs(const struct iovec *iovecs, unsigned nr) 162 { 163 unsigned i; 164 165 if (__asan_address_is_poisoned((void *)iovecs) != 0) { 166 __asan_describe_address((void *)iovecs); 167 exit(1); 168 } 169 170 for (i = 0; i < nr; i++) { 171 if (__asan_region_is_poisoned((void *)iovecs[i].iov_base, iovecs[i].iov_len) != 0) { 172 __asan_describe_address((void *)iovecs[i].iov_base); 173 exit(1); 174 } 175 } 176 } 177