polyphony 0.84 → 0.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/Gemfile.lock +1 -1
  4. data/Rakefile +1 -1
  5. data/examples/core/multi_suspend.rb +39 -0
  6. data/examples/core/shutdown_all_children.rb +41 -0
  7. data/examples/io/gzip.rb +8 -0
  8. data/examples/io/splice_echo_server.rb +15 -0
  9. data/ext/polyphony/backend_io_uring.c +57 -31
  10. data/ext/polyphony/io_extensions.c +137 -26
  11. data/lib/polyphony/extensions/fiber.rb +3 -1
  12. data/lib/polyphony/extensions/io.rb +4 -0
  13. data/lib/polyphony/extensions/pipe.rb +4 -0
  14. data/lib/polyphony/extensions/socket.rb +4 -0
  15. data/lib/polyphony/version.rb +1 -1
  16. data/polyphony.gemspec +1 -1
  17. data/test/test_backend.rb +1 -1
  18. data/test/test_fiber.rb +5 -2
  19. data/test/test_signal.rb +3 -3
  20. data/vendor/liburing/.github/pull_request_template.md +86 -0
  21. data/vendor/liburing/.github/workflows/build.yml +85 -0
  22. data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
  23. data/vendor/liburing/.gitignore +149 -0
  24. data/vendor/liburing/COPYING +502 -0
  25. data/vendor/liburing/COPYING.GPL +339 -0
  26. data/vendor/liburing/LICENSE +7 -0
  27. data/vendor/liburing/Makefile +82 -0
  28. data/vendor/liburing/Makefile.common +5 -0
  29. data/vendor/liburing/Makefile.quiet +11 -0
  30. data/vendor/liburing/README +46 -0
  31. data/vendor/liburing/configure +486 -0
  32. data/vendor/liburing/debian/README.Debian +7 -0
  33. data/vendor/liburing/debian/changelog +27 -0
  34. data/vendor/liburing/debian/compat +1 -0
  35. data/vendor/liburing/debian/control +48 -0
  36. data/vendor/liburing/debian/copyright +49 -0
  37. data/vendor/liburing/debian/liburing-dev.install +4 -0
  38. data/vendor/liburing/debian/liburing-dev.manpages +6 -0
  39. data/vendor/liburing/debian/liburing1-udeb.install +1 -0
  40. data/vendor/liburing/debian/liburing1.install +1 -0
  41. data/vendor/liburing/debian/liburing1.symbols +32 -0
  42. data/vendor/liburing/debian/patches/series +1 -0
  43. data/vendor/liburing/debian/rules +81 -0
  44. data/vendor/liburing/debian/source/format +1 -0
  45. data/vendor/liburing/debian/source/local-options +2 -0
  46. data/vendor/liburing/debian/source/options +1 -0
  47. data/vendor/liburing/debian/watch +3 -0
  48. data/vendor/liburing/examples/Makefile +38 -0
  49. data/vendor/liburing/examples/io_uring-cp.c +282 -0
  50. data/vendor/liburing/examples/io_uring-test.c +112 -0
  51. data/vendor/liburing/examples/link-cp.c +193 -0
  52. data/vendor/liburing/examples/ucontext-cp.c +273 -0
  53. data/vendor/liburing/liburing.pc.in +12 -0
  54. data/vendor/liburing/liburing.spec +66 -0
  55. data/vendor/liburing/make-debs.sh +53 -0
  56. data/vendor/liburing/man/io_uring.7 +754 -0
  57. data/vendor/liburing/man/io_uring_cq_advance.3 +35 -0
  58. data/vendor/liburing/man/io_uring_cq_ready.3 +25 -0
  59. data/vendor/liburing/man/io_uring_cqe_get_data.3 +34 -0
  60. data/vendor/liburing/man/io_uring_cqe_seen.3 +32 -0
  61. data/vendor/liburing/man/io_uring_enter.2 +1483 -0
  62. data/vendor/liburing/man/io_uring_free_probe.3 +24 -0
  63. data/vendor/liburing/man/io_uring_get_probe.3 +29 -0
  64. data/vendor/liburing/man/io_uring_get_sqe.3 +38 -0
  65. data/vendor/liburing/man/io_uring_opcode_supported.3 +29 -0
  66. data/vendor/liburing/man/io_uring_prep_msg_ring.3 +58 -0
  67. data/vendor/liburing/man/io_uring_prep_read.3 +50 -0
  68. data/vendor/liburing/man/io_uring_prep_read_fixed.3 +54 -0
  69. data/vendor/liburing/man/io_uring_prep_readv.3 +51 -0
  70. data/vendor/liburing/man/io_uring_prep_readv2.3 +79 -0
  71. data/vendor/liburing/man/io_uring_prep_write.3 +50 -0
  72. data/vendor/liburing/man/io_uring_prep_write_fixed.3 +54 -0
  73. data/vendor/liburing/man/io_uring_prep_writev.3 +51 -0
  74. data/vendor/liburing/man/io_uring_prep_writev2.3 +78 -0
  75. data/vendor/liburing/man/io_uring_queue_exit.3 +27 -0
  76. data/vendor/liburing/man/io_uring_queue_init.3 +44 -0
  77. data/vendor/liburing/man/io_uring_register.2 +688 -0
  78. data/vendor/liburing/man/io_uring_register_buffers.3 +41 -0
  79. data/vendor/liburing/man/io_uring_register_files.3 +35 -0
  80. data/vendor/liburing/man/io_uring_setup.2 +534 -0
  81. data/vendor/liburing/man/io_uring_sq_ready.3 +25 -0
  82. data/vendor/liburing/man/io_uring_sq_space_left.3 +25 -0
  83. data/vendor/liburing/man/io_uring_sqe_set_data.3 +30 -0
  84. data/vendor/liburing/man/io_uring_sqe_set_flags.3 +60 -0
  85. data/vendor/liburing/man/io_uring_sqring_wait.3 +30 -0
  86. data/vendor/liburing/man/io_uring_submit.3 +29 -0
  87. data/vendor/liburing/man/io_uring_submit_and_wait.3 +34 -0
  88. data/vendor/liburing/man/io_uring_submit_and_wait_timeout.3 +49 -0
  89. data/vendor/liburing/man/io_uring_unregister_buffers.3 +26 -0
  90. data/vendor/liburing/man/io_uring_unregister_files.3 +26 -0
  91. data/vendor/liburing/man/io_uring_wait_cqe.3 +33 -0
  92. data/vendor/liburing/man/io_uring_wait_cqe_nr.3 +36 -0
  93. data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +39 -0
  94. data/vendor/liburing/man/io_uring_wait_cqes.3 +46 -0
  95. data/vendor/liburing/src/Makefile +89 -0
  96. data/vendor/liburing/src/arch/aarch64/syscall.h +95 -0
  97. data/vendor/liburing/src/arch/generic/lib.h +21 -0
  98. data/vendor/liburing/src/arch/generic/syscall.h +87 -0
  99. data/vendor/liburing/src/arch/syscall-defs.h +67 -0
  100. data/vendor/liburing/src/arch/x86/lib.h +32 -0
  101. data/vendor/liburing/src/arch/x86/syscall.h +160 -0
  102. data/vendor/liburing/src/include/liburing/barrier.h +81 -0
  103. data/vendor/liburing/src/include/liburing/io_uring.h +442 -0
  104. data/vendor/liburing/src/include/liburing.h +921 -0
  105. data/vendor/liburing/src/int_flags.h +8 -0
  106. data/vendor/liburing/src/lib.h +57 -0
  107. data/vendor/liburing/src/liburing.map +53 -0
  108. data/vendor/liburing/src/nolibc.c +48 -0
  109. data/vendor/liburing/src/queue.c +403 -0
  110. data/vendor/liburing/src/register.c +293 -0
  111. data/vendor/liburing/src/setup.c +332 -0
  112. data/vendor/liburing/src/syscall.c +47 -0
  113. data/vendor/liburing/src/syscall.h +103 -0
  114. data/vendor/liburing/test/232c93d07b74-test.c +306 -0
  115. data/vendor/liburing/test/35fa71a030ca-test.c +329 -0
  116. data/vendor/liburing/test/500f9fbadef8-test.c +89 -0
  117. data/vendor/liburing/test/7ad0e4b2f83c-test.c +93 -0
  118. data/vendor/liburing/test/8a9973408177-test.c +106 -0
  119. data/vendor/liburing/test/917257daa0fe-test.c +53 -0
  120. data/vendor/liburing/test/Makefile +244 -0
  121. data/vendor/liburing/test/a0908ae19763-test.c +58 -0
  122. data/vendor/liburing/test/a4c0b3decb33-test.c +180 -0
  123. data/vendor/liburing/test/accept-link.c +254 -0
  124. data/vendor/liburing/test/accept-reuse.c +164 -0
  125. data/vendor/liburing/test/accept-test.c +79 -0
  126. data/vendor/liburing/test/accept.c +477 -0
  127. data/vendor/liburing/test/across-fork.c +283 -0
  128. data/vendor/liburing/test/b19062a56726-test.c +53 -0
  129. data/vendor/liburing/test/b5837bd5311d-test.c +77 -0
  130. data/vendor/liburing/test/ce593a6c480a-test.c +136 -0
  131. data/vendor/liburing/test/close-opath.c +122 -0
  132. data/vendor/liburing/test/config +10 -0
  133. data/vendor/liburing/test/connect.c +398 -0
  134. data/vendor/liburing/test/cq-full.c +96 -0
  135. data/vendor/liburing/test/cq-overflow.c +294 -0
  136. data/vendor/liburing/test/cq-peek-batch.c +102 -0
  137. data/vendor/liburing/test/cq-ready.c +94 -0
  138. data/vendor/liburing/test/cq-size.c +64 -0
  139. data/vendor/liburing/test/d4ae271dfaae-test.c +96 -0
  140. data/vendor/liburing/test/d77a67ed5f27-test.c +65 -0
  141. data/vendor/liburing/test/defer.c +307 -0
  142. data/vendor/liburing/test/double-poll-crash.c +185 -0
  143. data/vendor/liburing/test/drop-submit.c +92 -0
  144. data/vendor/liburing/test/eeed8b54e0df-test.c +114 -0
  145. data/vendor/liburing/test/empty-eownerdead.c +45 -0
  146. data/vendor/liburing/test/eventfd-disable.c +151 -0
  147. data/vendor/liburing/test/eventfd-reg.c +76 -0
  148. data/vendor/liburing/test/eventfd-ring.c +97 -0
  149. data/vendor/liburing/test/eventfd.c +112 -0
  150. data/vendor/liburing/test/exec-target.c +6 -0
  151. data/vendor/liburing/test/exit-no-cleanup.c +117 -0
  152. data/vendor/liburing/test/fadvise.c +202 -0
  153. data/vendor/liburing/test/fallocate.c +249 -0
  154. data/vendor/liburing/test/fc2a85cb02ef-test.c +131 -0
  155. data/vendor/liburing/test/file-register.c +858 -0
  156. data/vendor/liburing/test/file-update.c +173 -0
  157. data/vendor/liburing/test/file-verify.c +629 -0
  158. data/vendor/liburing/test/files-exit-hang-poll.c +128 -0
  159. data/vendor/liburing/test/files-exit-hang-timeout.c +134 -0
  160. data/vendor/liburing/test/fixed-link.c +90 -0
  161. data/vendor/liburing/test/fpos.c +252 -0
  162. data/vendor/liburing/test/fsync.c +224 -0
  163. data/vendor/liburing/test/hardlink.c +136 -0
  164. data/vendor/liburing/test/helpers.c +135 -0
  165. data/vendor/liburing/test/helpers.h +67 -0
  166. data/vendor/liburing/test/io-cancel.c +550 -0
  167. data/vendor/liburing/test/io_uring_enter.c +296 -0
  168. data/vendor/liburing/test/io_uring_register.c +676 -0
  169. data/vendor/liburing/test/io_uring_setup.c +192 -0
  170. data/vendor/liburing/test/iopoll.c +372 -0
  171. data/vendor/liburing/test/lfs-openat-write.c +119 -0
  172. data/vendor/liburing/test/lfs-openat.c +275 -0
  173. data/vendor/liburing/test/link-timeout.c +1107 -0
  174. data/vendor/liburing/test/link.c +496 -0
  175. data/vendor/liburing/test/link_drain.c +229 -0
  176. data/vendor/liburing/test/madvise.c +195 -0
  177. data/vendor/liburing/test/mkdir.c +108 -0
  178. data/vendor/liburing/test/msg-ring.c +234 -0
  179. data/vendor/liburing/test/multicqes_drain.c +387 -0
  180. data/vendor/liburing/test/nop-all-sizes.c +99 -0
  181. data/vendor/liburing/test/nop.c +115 -0
  182. data/vendor/liburing/test/open-close.c +261 -0
  183. data/vendor/liburing/test/openat2.c +308 -0
  184. data/vendor/liburing/test/personality.c +204 -0
  185. data/vendor/liburing/test/pipe-eof.c +83 -0
  186. data/vendor/liburing/test/pipe-reuse.c +105 -0
  187. data/vendor/liburing/test/poll-cancel-ton.c +135 -0
  188. data/vendor/liburing/test/poll-cancel.c +228 -0
  189. data/vendor/liburing/test/poll-link.c +230 -0
  190. data/vendor/liburing/test/poll-many.c +208 -0
  191. data/vendor/liburing/test/poll-mshot-update.c +273 -0
  192. data/vendor/liburing/test/poll-ring.c +48 -0
  193. data/vendor/liburing/test/poll-v-poll.c +353 -0
  194. data/vendor/liburing/test/poll.c +109 -0
  195. data/vendor/liburing/test/pollfree.c +426 -0
  196. data/vendor/liburing/test/probe.c +135 -0
  197. data/vendor/liburing/test/read-write.c +876 -0
  198. data/vendor/liburing/test/register-restrictions.c +633 -0
  199. data/vendor/liburing/test/rename.c +135 -0
  200. data/vendor/liburing/test/ring-leak.c +173 -0
  201. data/vendor/liburing/test/ring-leak2.c +249 -0
  202. data/vendor/liburing/test/rsrc_tags.c +449 -0
  203. data/vendor/liburing/test/runtests-loop.sh +16 -0
  204. data/vendor/liburing/test/runtests.sh +170 -0
  205. data/vendor/liburing/test/rw_merge_test.c +97 -0
  206. data/vendor/liburing/test/self.c +91 -0
  207. data/vendor/liburing/test/send_recv.c +286 -0
  208. data/vendor/liburing/test/send_recvmsg.c +345 -0
  209. data/vendor/liburing/test/sendmsg_fs_cve.c +200 -0
  210. data/vendor/liburing/test/shared-wq.c +84 -0
  211. data/vendor/liburing/test/short-read.c +75 -0
  212. data/vendor/liburing/test/shutdown.c +165 -0
  213. data/vendor/liburing/test/sigfd-deadlock.c +74 -0
  214. data/vendor/liburing/test/skip-cqe.c +429 -0
  215. data/vendor/liburing/test/socket-rw-eagain.c +158 -0
  216. data/vendor/liburing/test/socket-rw-offset.c +157 -0
  217. data/vendor/liburing/test/socket-rw.c +145 -0
  218. data/vendor/liburing/test/splice.c +512 -0
  219. data/vendor/liburing/test/sq-full-cpp.cc +45 -0
  220. data/vendor/liburing/test/sq-full.c +45 -0
  221. data/vendor/liburing/test/sq-poll-dup.c +204 -0
  222. data/vendor/liburing/test/sq-poll-kthread.c +169 -0
  223. data/vendor/liburing/test/sq-poll-share.c +137 -0
  224. data/vendor/liburing/test/sq-space_left.c +159 -0
  225. data/vendor/liburing/test/sqpoll-cancel-hang.c +157 -0
  226. data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
  227. data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
  228. data/vendor/liburing/test/sqpoll-sleep.c +69 -0
  229. data/vendor/liburing/test/statx.c +172 -0
  230. data/vendor/liburing/test/stdout.c +232 -0
  231. data/vendor/liburing/test/submit-link-fail.c +154 -0
  232. data/vendor/liburing/test/submit-reuse.c +239 -0
  233. data/vendor/liburing/test/symlink.c +116 -0
  234. data/vendor/liburing/test/teardowns.c +58 -0
  235. data/vendor/liburing/test/thread-exit.c +143 -0
  236. data/vendor/liburing/test/timeout-new.c +252 -0
  237. data/vendor/liburing/test/timeout-overflow.c +204 -0
  238. data/vendor/liburing/test/timeout.c +1523 -0
  239. data/vendor/liburing/test/unlink.c +112 -0
  240. data/vendor/liburing/test/wakeup-hang.c +162 -0
  241. metadata +227 -2
@@ -0,0 +1,109 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test io_uring poll handling
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <signal.h>
12
+ #include <poll.h>
13
+ #include <sys/wait.h>
14
+
15
+ #include "liburing.h"
16
+
17
+ static void sig_alrm(int sig)
18
+ {
19
+ fprintf(stderr, "Timed out!\n");
20
+ exit(1);
21
+ }
22
+
23
+ int main(int argc, char *argv[])
24
+ {
25
+ struct io_uring_cqe *cqe;
26
+ struct io_uring_sqe *sqe;
27
+ struct io_uring ring;
28
+ int pipe1[2];
29
+ pid_t p;
30
+ int ret;
31
+
32
+ if (argc > 1)
33
+ return 0;
34
+
35
+ if (pipe(pipe1) != 0) {
36
+ perror("pipe");
37
+ return 1;
38
+ }
39
+
40
+ p = fork();
41
+ switch (p) {
42
+ case -1:
43
+ perror("fork");
44
+ exit(2);
45
+ case 0: {
46
+ struct sigaction act;
47
+
48
+ ret = io_uring_queue_init(1, &ring, 0);
49
+ if (ret) {
50
+ fprintf(stderr, "child: ring setup failed: %d\n", ret);
51
+ return 1;
52
+ }
53
+
54
+ memset(&act, 0, sizeof(act));
55
+ act.sa_handler = sig_alrm;
56
+ act.sa_flags = SA_RESTART;
57
+ sigaction(SIGALRM, &act, NULL);
58
+ alarm(1);
59
+
60
+ sqe = io_uring_get_sqe(&ring);
61
+ if (!sqe) {
62
+ fprintf(stderr, "get sqe failed\n");
63
+ return 1;
64
+ }
65
+
66
+ io_uring_prep_poll_add(sqe, pipe1[0], POLLIN);
67
+ io_uring_sqe_set_data(sqe, sqe);
68
+
69
+ ret = io_uring_submit(&ring);
70
+ if (ret <= 0) {
71
+ fprintf(stderr, "child: sqe submit failed: %d\n", ret);
72
+ return 1;
73
+ }
74
+
75
+ do {
76
+ ret = io_uring_wait_cqe(&ring, &cqe);
77
+ if (ret < 0) {
78
+ fprintf(stderr, "child: wait completion %d\n", ret);
79
+ break;
80
+ }
81
+ io_uring_cqe_seen(&ring, cqe);
82
+ } while (ret != 0);
83
+
84
+ if (ret < 0)
85
+ return 1;
86
+ if (cqe->user_data != (unsigned long) sqe) {
87
+ fprintf(stderr, "child: cqe doesn't match sqe\n");
88
+ return 1;
89
+ }
90
+ if ((cqe->res & POLLIN) != POLLIN) {
91
+ fprintf(stderr, "child: bad return value %ld\n",
92
+ (long) cqe->res);
93
+ return 1;
94
+ }
95
+ exit(0);
96
+ }
97
+ default:
98
+ do {
99
+ errno = 0;
100
+ ret = write(pipe1[1], "foo", 3);
101
+ } while (ret == -1 && errno == EINTR);
102
+
103
+ if (ret != 3) {
104
+ fprintf(stderr, "parent: bad write return %d\n", ret);
105
+ return 1;
106
+ }
107
+ return 0;
108
+ }
109
+ }
@@ -0,0 +1,426 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ // https://syzkaller.appspot.com/bug?id=5f5a44abb4cba056fe24255c4fcb7e7bbe13de7a
3
+ // autogenerated by syzkaller (https://github.com/google/syzkaller)
4
+
5
+ #include <dirent.h>
6
+ #include <endian.h>
7
+ #include <errno.h>
8
+ #include <fcntl.h>
9
+ #include <pthread.h>
10
+ #include <signal.h>
11
+ #include <stdarg.h>
12
+ #include <stdbool.h>
13
+ #include <stdint.h>
14
+ #include <stdio.h>
15
+ #include <stdlib.h>
16
+ #include <string.h>
17
+ #include <sys/mman.h>
18
+ #include <sys/prctl.h>
19
+ #include <sys/stat.h>
20
+ #include <sys/syscall.h>
21
+ #include <sys/types.h>
22
+ #include <sys/wait.h>
23
+ #include <time.h>
24
+ #include <unistd.h>
25
+
26
+ #include <linux/futex.h>
27
+
28
+ #ifdef __NR_futex
29
+
30
+ static void sleep_ms(uint64_t ms)
31
+ {
32
+ usleep(ms * 1000);
33
+ }
34
+
35
+ static uint64_t current_time_ms(void)
36
+ {
37
+ struct timespec ts;
38
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
39
+ exit(1);
40
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
41
+ }
42
+
43
+ static void thread_start(void* (*fn)(void*), void* arg)
44
+ {
45
+ pthread_t th;
46
+ pthread_attr_t attr;
47
+ pthread_attr_init(&attr);
48
+ pthread_attr_setstacksize(&attr, 128 << 10);
49
+ int i = 0;
50
+ for (; i < 100; i++) {
51
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
52
+ pthread_attr_destroy(&attr);
53
+ return;
54
+ }
55
+ if (errno == EAGAIN) {
56
+ usleep(50);
57
+ continue;
58
+ }
59
+ break;
60
+ }
61
+ exit(1);
62
+ }
63
+
64
+ typedef struct {
65
+ int state;
66
+ } event_t;
67
+
68
+ static void event_init(event_t* ev)
69
+ {
70
+ ev->state = 0;
71
+ }
72
+
73
+ static void event_reset(event_t* ev)
74
+ {
75
+ ev->state = 0;
76
+ }
77
+
78
+ static void event_set(event_t* ev)
79
+ {
80
+ if (ev->state)
81
+ exit(1);
82
+ __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
83
+ syscall(__NR_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1000000);
84
+ }
85
+
86
+ static void event_wait(event_t* ev)
87
+ {
88
+ while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
89
+ syscall(__NR_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
90
+ }
91
+
92
+ static int event_isset(event_t* ev)
93
+ {
94
+ return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
95
+ }
96
+
97
+ static int event_timedwait(event_t* ev, uint64_t timeout)
98
+ {
99
+ uint64_t start = current_time_ms();
100
+ uint64_t now = start;
101
+ for (;;) {
102
+ uint64_t remain = timeout - (now - start);
103
+ struct timespec ts;
104
+ ts.tv_sec = remain / 1000;
105
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
106
+ syscall(__NR_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
107
+ if (__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
108
+ return 1;
109
+ now = current_time_ms();
110
+ if (now - start > timeout)
111
+ return 0;
112
+ }
113
+ }
114
+
115
+ #define SIZEOF_IO_URING_SQE 64
116
+ #define SIZEOF_IO_URING_CQE 16
117
+ #define SQ_HEAD_OFFSET 0
118
+ #define SQ_TAIL_OFFSET 64
119
+ #define SQ_RING_MASK_OFFSET 256
120
+ #define SQ_RING_ENTRIES_OFFSET 264
121
+ #define SQ_FLAGS_OFFSET 276
122
+ #define SQ_DROPPED_OFFSET 272
123
+ #define CQ_HEAD_OFFSET 128
124
+ #define CQ_TAIL_OFFSET 192
125
+ #define CQ_RING_MASK_OFFSET 260
126
+ #define CQ_RING_ENTRIES_OFFSET 268
127
+ #define CQ_RING_OVERFLOW_OFFSET 284
128
+ #define CQ_FLAGS_OFFSET 280
129
+ #define CQ_CQES_OFFSET 320
130
+
131
+ struct io_sqring_offsets {
132
+ uint32_t head;
133
+ uint32_t tail;
134
+ uint32_t ring_mask;
135
+ uint32_t ring_entries;
136
+ uint32_t flags;
137
+ uint32_t dropped;
138
+ uint32_t array;
139
+ uint32_t resv1;
140
+ uint64_t resv2;
141
+ };
142
+
143
+ struct io_cqring_offsets {
144
+ uint32_t head;
145
+ uint32_t tail;
146
+ uint32_t ring_mask;
147
+ uint32_t ring_entries;
148
+ uint32_t overflow;
149
+ uint32_t cqes;
150
+ uint64_t resv[2];
151
+ };
152
+
153
+ struct io_uring_params {
154
+ uint32_t sq_entries;
155
+ uint32_t cq_entries;
156
+ uint32_t flags;
157
+ uint32_t sq_thread_cpu;
158
+ uint32_t sq_thread_idle;
159
+ uint32_t features;
160
+ uint32_t resv[4];
161
+ struct io_sqring_offsets sq_off;
162
+ struct io_cqring_offsets cq_off;
163
+ };
164
+
165
+ #define IORING_OFF_SQ_RING 0
166
+ #define IORING_OFF_SQES 0x10000000ULL
167
+
168
+ #define sys_io_uring_setup 425
169
+ static long syz_io_uring_setup(volatile long a0, volatile long a1,
170
+ volatile long a2, volatile long a3,
171
+ volatile long a4, volatile long a5)
172
+ {
173
+ uint32_t entries = (uint32_t)a0;
174
+ struct io_uring_params* setup_params = (struct io_uring_params*)a1;
175
+ void* vma1 = (void*)a2;
176
+ void* vma2 = (void*)a3;
177
+ void** ring_ptr_out = (void**)a4;
178
+ void** sqes_ptr_out = (void**)a5;
179
+ uint32_t fd_io_uring = syscall(sys_io_uring_setup, entries, setup_params);
180
+ uint32_t sq_ring_sz =
181
+ setup_params->sq_off.array + setup_params->sq_entries * sizeof(uint32_t);
182
+ uint32_t cq_ring_sz = setup_params->cq_off.cqes +
183
+ setup_params->cq_entries * SIZEOF_IO_URING_CQE;
184
+ uint32_t ring_sz = sq_ring_sz > cq_ring_sz ? sq_ring_sz : cq_ring_sz;
185
+ *ring_ptr_out = mmap(vma1, ring_sz, PROT_READ | PROT_WRITE,
186
+ MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring,
187
+ IORING_OFF_SQ_RING);
188
+ uint32_t sqes_sz = setup_params->sq_entries * SIZEOF_IO_URING_SQE;
189
+ *sqes_ptr_out =
190
+ mmap(vma2, sqes_sz, PROT_READ | PROT_WRITE,
191
+ MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring, IORING_OFF_SQES);
192
+ return fd_io_uring;
193
+ }
194
+
195
+ static long syz_io_uring_submit(volatile long a0, volatile long a1,
196
+ volatile long a2, volatile long a3)
197
+ {
198
+ char* ring_ptr = (char*)a0;
199
+ char* sqes_ptr = (char*)a1;
200
+ char* sqe = (char*)a2;
201
+ uint32_t sqes_index = (uint32_t)a3;
202
+ uint32_t sq_ring_entries = *(uint32_t*)(ring_ptr + SQ_RING_ENTRIES_OFFSET);
203
+ uint32_t cq_ring_entries = *(uint32_t*)(ring_ptr + CQ_RING_ENTRIES_OFFSET);
204
+ uint32_t sq_array_off =
205
+ (CQ_CQES_OFFSET + cq_ring_entries * SIZEOF_IO_URING_CQE + 63) & ~63;
206
+ if (sq_ring_entries)
207
+ sqes_index %= sq_ring_entries;
208
+ char* sqe_dest = sqes_ptr + sqes_index * SIZEOF_IO_URING_SQE;
209
+ memcpy(sqe_dest, sqe, SIZEOF_IO_URING_SQE);
210
+ uint32_t sq_ring_mask = *(uint32_t*)(ring_ptr + SQ_RING_MASK_OFFSET);
211
+ uint32_t* sq_tail_ptr = (uint32_t*)(ring_ptr + SQ_TAIL_OFFSET);
212
+ uint32_t sq_tail = *sq_tail_ptr & sq_ring_mask;
213
+ uint32_t sq_tail_next = *sq_tail_ptr + 1;
214
+ uint32_t* sq_array = (uint32_t*)(ring_ptr + sq_array_off);
215
+ *(sq_array + sq_tail) = sqes_index;
216
+ __atomic_store_n(sq_tail_ptr, sq_tail_next, __ATOMIC_RELEASE);
217
+ return 0;
218
+ }
219
+
220
+ static void kill_and_wait(int pid, int* status)
221
+ {
222
+ kill(-pid, SIGKILL);
223
+ kill(pid, SIGKILL);
224
+ for (int i = 0; i < 100; i++) {
225
+ if (waitpid(-1, status, WNOHANG | __WALL) == pid)
226
+ return;
227
+ usleep(1000);
228
+ }
229
+ DIR* dir = opendir("/sys/fs/fuse/connections");
230
+ if (dir) {
231
+ for (;;) {
232
+ struct dirent* ent = readdir(dir);
233
+ if (!ent)
234
+ break;
235
+ if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
236
+ continue;
237
+ char abort[300];
238
+ snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
239
+ ent->d_name);
240
+ int fd = open(abort, O_WRONLY);
241
+ if (fd == -1) {
242
+ continue;
243
+ }
244
+ if (write(fd, abort, 1) < 0) {
245
+ }
246
+ close(fd);
247
+ }
248
+ closedir(dir);
249
+ } else {
250
+ }
251
+ while (waitpid(-1, status, __WALL) != pid) {
252
+ }
253
+ }
254
+
255
+ static void setup_test()
256
+ {
257
+ prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
258
+ setpgrp();
259
+ }
260
+
261
+ struct thread_t {
262
+ int created, call;
263
+ event_t ready, done;
264
+ };
265
+
266
+ static struct thread_t threads[16];
267
+ static void execute_call(int call);
268
+ static int running;
269
+
270
+ static void* thr(void* arg)
271
+ {
272
+ struct thread_t* th = (struct thread_t*)arg;
273
+ for (;;) {
274
+ event_wait(&th->ready);
275
+ event_reset(&th->ready);
276
+ execute_call(th->call);
277
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
278
+ event_set(&th->done);
279
+ }
280
+ return 0;
281
+ }
282
+
283
+ static void execute_one(void)
284
+ {
285
+ int i, call, thread;
286
+ for (call = 0; call < 4; call++) {
287
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
288
+ thread++) {
289
+ struct thread_t* th = &threads[thread];
290
+ if (!th->created) {
291
+ th->created = 1;
292
+ event_init(&th->ready);
293
+ event_init(&th->done);
294
+ event_set(&th->done);
295
+ thread_start(thr, th);
296
+ }
297
+ if (!event_isset(&th->done))
298
+ continue;
299
+ event_reset(&th->done);
300
+ th->call = call;
301
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
302
+ event_set(&th->ready);
303
+ event_timedwait(&th->done, 50);
304
+ break;
305
+ }
306
+ }
307
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
308
+ sleep_ms(1);
309
+ }
310
+
311
+ static void execute_one(void);
312
+
313
+ #define WAIT_FLAGS __WALL
314
+
315
+ static void loop(void)
316
+ {
317
+ int iter = 0;
318
+ for (; iter < 5000; iter++) {
319
+ int pid = fork();
320
+ if (pid < 0)
321
+ exit(1);
322
+ if (pid == 0) {
323
+ setup_test();
324
+ execute_one();
325
+ exit(0);
326
+ }
327
+ int status = 0;
328
+ uint64_t start = current_time_ms();
329
+ for (;;) {
330
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
331
+ break;
332
+ sleep_ms(1);
333
+ if (current_time_ms() - start < 5000)
334
+ continue;
335
+ kill_and_wait(pid, &status);
336
+ break;
337
+ }
338
+ }
339
+ }
340
+
341
+ #ifndef __NR_io_uring_enter
342
+ #define __NR_io_uring_enter 426
343
+ #endif
344
+
345
+ uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0};
346
+
347
+ void execute_call(int call)
348
+ {
349
+ intptr_t res = 0;
350
+ switch (call) {
351
+ case 0:
352
+ *(uint64_t*)0x200000c0 = 0;
353
+ res = syscall(__NR_signalfd4, -1, 0x200000c0ul, 8ul, 0ul);
354
+ if (res != -1)
355
+ r[0] = res;
356
+ break;
357
+ case 1:
358
+ *(uint32_t*)0x20000a84 = 0;
359
+ *(uint32_t*)0x20000a88 = 0;
360
+ *(uint32_t*)0x20000a8c = 0;
361
+ *(uint32_t*)0x20000a90 = 0;
362
+ *(uint32_t*)0x20000a98 = -1;
363
+ memset((void*)0x20000a9c, 0, 12);
364
+ res = -1;
365
+ res = syz_io_uring_setup(0x87, 0x20000a80, 0x206d6000, 0x206d7000,
366
+ 0x20000000, 0x20000040);
367
+ if (res != -1) {
368
+ r[1] = res;
369
+ r[2] = *(uint64_t*)0x20000000;
370
+ r[3] = *(uint64_t*)0x20000040;
371
+ }
372
+ break;
373
+ case 2:
374
+ *(uint8_t*)0x20002240 = 6;
375
+ *(uint8_t*)0x20002241 = 0;
376
+ *(uint16_t*)0x20002242 = 0;
377
+ *(uint32_t*)0x20002244 = r[0];
378
+ *(uint64_t*)0x20002248 = 0;
379
+ *(uint64_t*)0x20002250 = 0;
380
+ *(uint32_t*)0x20002258 = 0;
381
+ *(uint16_t*)0x2000225c = 0;
382
+ *(uint16_t*)0x2000225e = 0;
383
+ *(uint64_t*)0x20002260 = 0;
384
+ *(uint16_t*)0x20002268 = 0;
385
+ *(uint16_t*)0x2000226a = 0;
386
+ memset((void*)0x2000226c, 0, 20);
387
+ syz_io_uring_submit(r[2], r[3], 0x20002240, 0);
388
+ break;
389
+ case 3:
390
+ syscall(__NR_io_uring_enter, r[1], 0x1523a, 0, 0ul, 0ul, 0xaul);
391
+ break;
392
+ }
393
+ }
394
+
395
+ int main(int argc, char *argv[])
396
+ {
397
+ void *ret;
398
+
399
+ #if !defined(__i386) && !defined(__x86_64__)
400
+ return 0;
401
+ #endif
402
+
403
+ if (argc > 1)
404
+ return 0;
405
+
406
+ ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
407
+ if (ret == MAP_FAILED)
408
+ return 0;
409
+ mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
410
+ if (ret == MAP_FAILED)
411
+ return 0;
412
+ mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
413
+ if (ret == MAP_FAILED)
414
+ return 0;
415
+ loop();
416
+ return 0;
417
+ }
418
+
419
+ #else /* __NR_futex */
420
+
421
+ int main(int argc, char *argv[])
422
+ {
423
+ return 0;
424
+ }
425
+
426
+ #endif /* __NR_futex */
@@ -0,0 +1,135 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test IORING_REGISTER_PROBE
4
+ */
5
+ #include <errno.h>
6
+ #include <stdio.h>
7
+ #include <unistd.h>
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+ #include <fcntl.h>
11
+
12
+ #include "helpers.h"
13
+ #include "liburing.h"
14
+
15
+ static int no_probe;
16
+
17
+ static int verify_probe(struct io_uring_probe *p, int full)
18
+ {
19
+ if (!full && p->ops_len) {
20
+ fprintf(stderr, "Got ops_len=%u\n", p->ops_len);
21
+ return 1;
22
+ }
23
+ if (!p->last_op) {
24
+ fprintf(stderr, "Got last_op=%u\n", p->last_op);
25
+ return 1;
26
+ }
27
+ if (!full)
28
+ return 0;
29
+ /* check a few ops that must be supported */
30
+ if (!(p->ops[IORING_OP_NOP].flags & IO_URING_OP_SUPPORTED)) {
31
+ fprintf(stderr, "NOP not supported!?\n");
32
+ return 1;
33
+ }
34
+ if (!(p->ops[IORING_OP_READV].flags & IO_URING_OP_SUPPORTED)) {
35
+ fprintf(stderr, "READV not supported!?\n");
36
+ return 1;
37
+ }
38
+ if (!(p->ops[IORING_OP_WRITE].flags & IO_URING_OP_SUPPORTED)) {
39
+ fprintf(stderr, "WRITE not supported!?\n");
40
+ return 1;
41
+ }
42
+
43
+ return 0;
44
+ }
45
+
46
+ static int test_probe_helper(struct io_uring *ring)
47
+ {
48
+ int ret;
49
+ struct io_uring_probe *p;
50
+
51
+ p = io_uring_get_probe_ring(ring);
52
+ if (!p) {
53
+ fprintf(stderr, "Failed getting probe data\n");
54
+ return 1;
55
+ }
56
+
57
+ ret = verify_probe(p, 1);
58
+ io_uring_free_probe(p);
59
+ return ret;
60
+ }
61
+
62
+ static int test_probe(struct io_uring *ring)
63
+ {
64
+ struct io_uring_probe *p;
65
+ size_t len;
66
+ int ret;
67
+
68
+ len = sizeof(*p) + 256 * sizeof(struct io_uring_probe_op);
69
+ p = t_calloc(1, len);
70
+ ret = io_uring_register_probe(ring, p, 0);
71
+ if (ret == -EINVAL) {
72
+ fprintf(stdout, "Probe not supported, skipping\n");
73
+ no_probe = 1;
74
+ goto out;
75
+ } else if (ret) {
76
+ fprintf(stdout, "Probe returned %d\n", ret);
77
+ goto err;
78
+ }
79
+
80
+ if (verify_probe(p, 0))
81
+ goto err;
82
+
83
+ /* now grab for all entries */
84
+ memset(p, 0, len);
85
+ ret = io_uring_register_probe(ring, p, 256);
86
+ if (ret == -EINVAL) {
87
+ fprintf(stdout, "Probe not supported, skipping\n");
88
+ goto err;
89
+ } else if (ret) {
90
+ fprintf(stdout, "Probe returned %d\n", ret);
91
+ goto err;
92
+ }
93
+
94
+ if (verify_probe(p, 1))
95
+ goto err;
96
+
97
+ out:
98
+ free(p);
99
+ return 0;
100
+ err:
101
+ free(p);
102
+ return 1;
103
+ }
104
+
105
+ int main(int argc, char *argv[])
106
+ {
107
+ struct io_uring ring;
108
+ int ret;
109
+
110
+ if (argc > 1)
111
+ return 0;
112
+
113
+ ret = io_uring_queue_init(8, &ring, 0);
114
+ if (ret) {
115
+ fprintf(stderr, "ring setup failed\n");
116
+ return 1;
117
+ }
118
+
119
+ ret = test_probe(&ring);
120
+ if (ret) {
121
+ fprintf(stderr, "test_probe failed\n");
122
+ return ret;
123
+ }
124
+ if (no_probe)
125
+ return 0;
126
+
127
+ ret = test_probe_helper(&ring);
128
+ if (ret) {
129
+ fprintf(stderr, "test_probe failed\n");
130
+ return ret;
131
+ }
132
+
133
+
134
+ return 0;
135
+ }