uringmachine 0.1

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 (307) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +12 -0
  3. data/.github/workflows/test.yml +35 -0
  4. data/.gitignore +59 -0
  5. data/.gitmodules +3 -0
  6. data/CHANGELOG.md +7 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +21 -0
  9. data/README.md +11 -0
  10. data/Rakefile +39 -0
  11. data/TODO.md +0 -0
  12. data/examples/echo_server.rb +52 -0
  13. data/examples/event_loop.rb +69 -0
  14. data/examples/fibers.rb +105 -0
  15. data/examples/http_server.rb +56 -0
  16. data/examples/http_server_multishot.rb +57 -0
  17. data/examples/http_server_simpler.rb +34 -0
  18. data/ext/um/extconf.rb +71 -0
  19. data/ext/um/iou.h +101 -0
  20. data/ext/um/op_ctx.c +138 -0
  21. data/ext/um/ring.c +755 -0
  22. data/ext/um/um.c +267 -0
  23. data/ext/um/um.h +97 -0
  24. data/ext/um/um_class.c +175 -0
  25. data/ext/um/um_ext.c +11 -0
  26. data/ext/um/um_op.c +87 -0
  27. data/ext/um/um_utils.c +23 -0
  28. data/lib/uringmachine/version.rb +3 -0
  29. data/lib/uringmachine.rb +8 -0
  30. data/test/helper.rb +70 -0
  31. data/test/test_iou.rb +876 -0
  32. data/test/test_um.rb +168 -0
  33. data/uringmachine.gemspec +27 -0
  34. data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
  35. data/vendor/liburing/.github/pull_request_template.md +86 -0
  36. data/vendor/liburing/.github/workflows/build.yml +137 -0
  37. data/vendor/liburing/.github/workflows/codespell.yml +25 -0
  38. data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
  39. data/vendor/liburing/.gitignore +41 -0
  40. data/vendor/liburing/CHANGELOG +111 -0
  41. data/vendor/liburing/CITATION.cff +11 -0
  42. data/vendor/liburing/COPYING +502 -0
  43. data/vendor/liburing/COPYING.GPL +339 -0
  44. data/vendor/liburing/LICENSE +20 -0
  45. data/vendor/liburing/Makefile +96 -0
  46. data/vendor/liburing/Makefile.common +7 -0
  47. data/vendor/liburing/Makefile.quiet +11 -0
  48. data/vendor/liburing/README +106 -0
  49. data/vendor/liburing/SECURITY.md +6 -0
  50. data/vendor/liburing/configure +624 -0
  51. data/vendor/liburing/debian/README.Debian +7 -0
  52. data/vendor/liburing/debian/changelog +38 -0
  53. data/vendor/liburing/debian/control +39 -0
  54. data/vendor/liburing/debian/copyright +49 -0
  55. data/vendor/liburing/debian/liburing-dev.install +4 -0
  56. data/vendor/liburing/debian/liburing-dev.manpages +5 -0
  57. data/vendor/liburing/debian/liburing2.install +1 -0
  58. data/vendor/liburing/debian/liburing2.symbols +56 -0
  59. data/vendor/liburing/debian/patches/series +1 -0
  60. data/vendor/liburing/debian/rules +29 -0
  61. data/vendor/liburing/debian/source/format +1 -0
  62. data/vendor/liburing/debian/source/local-options +2 -0
  63. data/vendor/liburing/debian/source/options +1 -0
  64. data/vendor/liburing/debian/watch +3 -0
  65. data/vendor/liburing/examples/Makefile +53 -0
  66. data/vendor/liburing/examples/helpers.c +62 -0
  67. data/vendor/liburing/examples/helpers.h +7 -0
  68. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  69. data/vendor/liburing/examples/io_uring-cp.c +282 -0
  70. data/vendor/liburing/examples/io_uring-test.c +112 -0
  71. data/vendor/liburing/examples/io_uring-udp.c +403 -0
  72. data/vendor/liburing/examples/link-cp.c +193 -0
  73. data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
  74. data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
  75. data/vendor/liburing/examples/poll-bench.c +101 -0
  76. data/vendor/liburing/examples/proxy.c +2461 -0
  77. data/vendor/liburing/examples/proxy.h +102 -0
  78. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  79. data/vendor/liburing/examples/send-zerocopy.c +658 -0
  80. data/vendor/liburing/examples/ucontext-cp.c +258 -0
  81. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  82. data/vendor/liburing/liburing.pc.in +12 -0
  83. data/vendor/liburing/liburing.spec +66 -0
  84. data/vendor/liburing/make-debs.sh +55 -0
  85. data/vendor/liburing/src/Makefile +129 -0
  86. data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
  87. data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
  88. data/vendor/liburing/src/arch/generic/lib.h +17 -0
  89. data/vendor/liburing/src/arch/generic/syscall.h +100 -0
  90. data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
  91. data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
  92. data/vendor/liburing/src/arch/syscall-defs.h +94 -0
  93. data/vendor/liburing/src/arch/x86/lib.h +11 -0
  94. data/vendor/liburing/src/arch/x86/syscall.h +296 -0
  95. data/vendor/liburing/src/ffi.c +15 -0
  96. data/vendor/liburing/src/include/liburing/barrier.h +81 -0
  97. data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
  98. data/vendor/liburing/src/include/liburing.h +1602 -0
  99. data/vendor/liburing/src/int_flags.h +11 -0
  100. data/vendor/liburing/src/lib.h +52 -0
  101. data/vendor/liburing/src/liburing-ffi.map +211 -0
  102. data/vendor/liburing/src/liburing.map +104 -0
  103. data/vendor/liburing/src/nolibc.c +55 -0
  104. data/vendor/liburing/src/queue.c +468 -0
  105. data/vendor/liburing/src/register.c +374 -0
  106. data/vendor/liburing/src/setup.c +689 -0
  107. data/vendor/liburing/src/setup.h +9 -0
  108. data/vendor/liburing/src/syscall.c +29 -0
  109. data/vendor/liburing/src/syscall.h +53 -0
  110. data/vendor/liburing/src/version.c +21 -0
  111. data/vendor/liburing/test/232c93d07b74.c +305 -0
  112. data/vendor/liburing/test/35fa71a030ca.c +329 -0
  113. data/vendor/liburing/test/500f9fbadef8.c +91 -0
  114. data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
  115. data/vendor/liburing/test/8a9973408177.c +107 -0
  116. data/vendor/liburing/test/917257daa0fe.c +54 -0
  117. data/vendor/liburing/test/Makefile +297 -0
  118. data/vendor/liburing/test/a0908ae19763.c +59 -0
  119. data/vendor/liburing/test/a4c0b3decb33.c +181 -0
  120. data/vendor/liburing/test/accept-link.c +255 -0
  121. data/vendor/liburing/test/accept-non-empty.c +256 -0
  122. data/vendor/liburing/test/accept-reuse.c +163 -0
  123. data/vendor/liburing/test/accept-test.c +83 -0
  124. data/vendor/liburing/test/accept.c +919 -0
  125. data/vendor/liburing/test/across-fork.c +284 -0
  126. data/vendor/liburing/test/b19062a56726.c +54 -0
  127. data/vendor/liburing/test/b5837bd5311d.c +78 -0
  128. data/vendor/liburing/test/bind-listen.c +408 -0
  129. data/vendor/liburing/test/buf-ring-nommap.c +123 -0
  130. data/vendor/liburing/test/buf-ring-put.c +83 -0
  131. data/vendor/liburing/test/buf-ring.c +473 -0
  132. data/vendor/liburing/test/ce593a6c480a.c +139 -0
  133. data/vendor/liburing/test/close-opath.c +123 -0
  134. data/vendor/liburing/test/config +14 -0
  135. data/vendor/liburing/test/connect-rep.c +204 -0
  136. data/vendor/liburing/test/connect.c +442 -0
  137. data/vendor/liburing/test/coredump.c +60 -0
  138. data/vendor/liburing/test/cq-full.c +97 -0
  139. data/vendor/liburing/test/cq-overflow.c +530 -0
  140. data/vendor/liburing/test/cq-peek-batch.c +103 -0
  141. data/vendor/liburing/test/cq-ready.c +95 -0
  142. data/vendor/liburing/test/cq-size.c +65 -0
  143. data/vendor/liburing/test/d4ae271dfaae.c +96 -0
  144. data/vendor/liburing/test/d77a67ed5f27.c +65 -0
  145. data/vendor/liburing/test/defer-taskrun.c +391 -0
  146. data/vendor/liburing/test/defer-tw-timeout.c +173 -0
  147. data/vendor/liburing/test/defer.c +319 -0
  148. data/vendor/liburing/test/double-poll-crash.c +195 -0
  149. data/vendor/liburing/test/drop-submit.c +94 -0
  150. data/vendor/liburing/test/eeed8b54e0df.c +120 -0
  151. data/vendor/liburing/test/empty-eownerdead.c +45 -0
  152. data/vendor/liburing/test/eploop.c +74 -0
  153. data/vendor/liburing/test/eventfd-disable.c +179 -0
  154. data/vendor/liburing/test/eventfd-reg.c +77 -0
  155. data/vendor/liburing/test/eventfd-ring.c +98 -0
  156. data/vendor/liburing/test/eventfd.c +113 -0
  157. data/vendor/liburing/test/evloop.c +73 -0
  158. data/vendor/liburing/test/exec-target.c +6 -0
  159. data/vendor/liburing/test/exit-no-cleanup.c +117 -0
  160. data/vendor/liburing/test/fadvise.c +202 -0
  161. data/vendor/liburing/test/fallocate.c +265 -0
  162. data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
  163. data/vendor/liburing/test/fd-install.c +500 -0
  164. data/vendor/liburing/test/fd-pass.c +237 -0
  165. data/vendor/liburing/test/fdinfo.c +419 -0
  166. data/vendor/liburing/test/file-register.c +1189 -0
  167. data/vendor/liburing/test/file-update.c +231 -0
  168. data/vendor/liburing/test/file-verify.c +654 -0
  169. data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
  170. data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
  171. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  172. data/vendor/liburing/test/fixed-buf-merge.c +101 -0
  173. data/vendor/liburing/test/fixed-hugepage.c +411 -0
  174. data/vendor/liburing/test/fixed-link.c +90 -0
  175. data/vendor/liburing/test/fixed-reuse.c +160 -0
  176. data/vendor/liburing/test/fpos.c +255 -0
  177. data/vendor/liburing/test/fsnotify.c +118 -0
  178. data/vendor/liburing/test/fsync.c +224 -0
  179. data/vendor/liburing/test/futex.c +571 -0
  180. data/vendor/liburing/test/hardlink.c +170 -0
  181. data/vendor/liburing/test/helpers.c +318 -0
  182. data/vendor/liburing/test/helpers.h +108 -0
  183. data/vendor/liburing/test/ignore-single-mmap.c +48 -0
  184. data/vendor/liburing/test/init-mem.c +164 -0
  185. data/vendor/liburing/test/io-cancel.c +561 -0
  186. data/vendor/liburing/test/io_uring_enter.c +264 -0
  187. data/vendor/liburing/test/io_uring_passthrough.c +482 -0
  188. data/vendor/liburing/test/io_uring_register.c +503 -0
  189. data/vendor/liburing/test/io_uring_setup.c +110 -0
  190. data/vendor/liburing/test/iopoll-leak.c +85 -0
  191. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  192. data/vendor/liburing/test/iopoll.c +465 -0
  193. data/vendor/liburing/test/lfs-openat-write.c +119 -0
  194. data/vendor/liburing/test/lfs-openat.c +273 -0
  195. data/vendor/liburing/test/link-timeout.c +1108 -0
  196. data/vendor/liburing/test/link.c +497 -0
  197. data/vendor/liburing/test/link_drain.c +255 -0
  198. data/vendor/liburing/test/madvise.c +195 -0
  199. data/vendor/liburing/test/min-timeout-wait.c +354 -0
  200. data/vendor/liburing/test/min-timeout.c +233 -0
  201. data/vendor/liburing/test/mkdir.c +112 -0
  202. data/vendor/liburing/test/msg-ring-fd.c +331 -0
  203. data/vendor/liburing/test/msg-ring-flags.c +212 -0
  204. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  205. data/vendor/liburing/test/msg-ring.c +467 -0
  206. data/vendor/liburing/test/multicqes_drain.c +429 -0
  207. data/vendor/liburing/test/napi-test.c +215 -0
  208. data/vendor/liburing/test/napi-test.sh +48 -0
  209. data/vendor/liburing/test/no-mmap-inval.c +42 -0
  210. data/vendor/liburing/test/nolibc.c +62 -0
  211. data/vendor/liburing/test/nop-all-sizes.c +99 -0
  212. data/vendor/liburing/test/nop.c +177 -0
  213. data/vendor/liburing/test/nvme.h +169 -0
  214. data/vendor/liburing/test/ooo-file-unreg.c +82 -0
  215. data/vendor/liburing/test/open-close.c +261 -0
  216. data/vendor/liburing/test/open-direct-link.c +188 -0
  217. data/vendor/liburing/test/open-direct-pick.c +180 -0
  218. data/vendor/liburing/test/openat2.c +312 -0
  219. data/vendor/liburing/test/personality.c +204 -0
  220. data/vendor/liburing/test/pipe-bug.c +95 -0
  221. data/vendor/liburing/test/pipe-eof.c +83 -0
  222. data/vendor/liburing/test/pipe-reuse.c +105 -0
  223. data/vendor/liburing/test/poll-cancel-all.c +496 -0
  224. data/vendor/liburing/test/poll-cancel-ton.c +135 -0
  225. data/vendor/liburing/test/poll-cancel.c +228 -0
  226. data/vendor/liburing/test/poll-link.c +221 -0
  227. data/vendor/liburing/test/poll-many.c +230 -0
  228. data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
  229. data/vendor/liburing/test/poll-mshot-update.c +323 -0
  230. data/vendor/liburing/test/poll-race-mshot.c +276 -0
  231. data/vendor/liburing/test/poll-race.c +105 -0
  232. data/vendor/liburing/test/poll-ring.c +48 -0
  233. data/vendor/liburing/test/poll-v-poll.c +353 -0
  234. data/vendor/liburing/test/poll.c +327 -0
  235. data/vendor/liburing/test/probe.c +135 -0
  236. data/vendor/liburing/test/read-before-exit.c +129 -0
  237. data/vendor/liburing/test/read-mshot-empty.c +153 -0
  238. data/vendor/liburing/test/read-mshot.c +404 -0
  239. data/vendor/liburing/test/read-write.c +1013 -0
  240. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  241. data/vendor/liburing/test/recv-msgall.c +263 -0
  242. data/vendor/liburing/test/recv-multishot.c +602 -0
  243. data/vendor/liburing/test/recvsend_bundle.c +691 -0
  244. data/vendor/liburing/test/reg-fd-only.c +131 -0
  245. data/vendor/liburing/test/reg-hint.c +56 -0
  246. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  247. data/vendor/liburing/test/regbuf-merge.c +91 -0
  248. data/vendor/liburing/test/register-restrictions.c +633 -0
  249. data/vendor/liburing/test/rename.c +132 -0
  250. data/vendor/liburing/test/ring-leak.c +283 -0
  251. data/vendor/liburing/test/ring-leak2.c +249 -0
  252. data/vendor/liburing/test/ringbuf-read.c +196 -0
  253. data/vendor/liburing/test/ringbuf-status.c +242 -0
  254. data/vendor/liburing/test/rsrc_tags.c +461 -0
  255. data/vendor/liburing/test/runtests-loop.sh +16 -0
  256. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  257. data/vendor/liburing/test/runtests.sh +168 -0
  258. data/vendor/liburing/test/rw_merge_test.c +98 -0
  259. data/vendor/liburing/test/self.c +91 -0
  260. data/vendor/liburing/test/send-zerocopy.c +971 -0
  261. data/vendor/liburing/test/send_recv.c +412 -0
  262. data/vendor/liburing/test/send_recvmsg.c +444 -0
  263. data/vendor/liburing/test/shared-wq.c +84 -0
  264. data/vendor/liburing/test/short-read.c +75 -0
  265. data/vendor/liburing/test/shutdown.c +165 -0
  266. data/vendor/liburing/test/sigfd-deadlock.c +88 -0
  267. data/vendor/liburing/test/single-issuer.c +169 -0
  268. data/vendor/liburing/test/skip-cqe.c +428 -0
  269. data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
  270. data/vendor/liburing/test/socket-io-cmd.c +237 -0
  271. data/vendor/liburing/test/socket-rw-eagain.c +149 -0
  272. data/vendor/liburing/test/socket-rw-offset.c +149 -0
  273. data/vendor/liburing/test/socket-rw.c +137 -0
  274. data/vendor/liburing/test/socket.c +408 -0
  275. data/vendor/liburing/test/splice.c +512 -0
  276. data/vendor/liburing/test/sq-full-cpp.cc +45 -0
  277. data/vendor/liburing/test/sq-full.c +45 -0
  278. data/vendor/liburing/test/sq-poll-dup.c +211 -0
  279. data/vendor/liburing/test/sq-poll-kthread.c +169 -0
  280. data/vendor/liburing/test/sq-poll-share.c +138 -0
  281. data/vendor/liburing/test/sq-space_left.c +159 -0
  282. data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
  283. data/vendor/liburing/test/sqpoll-exec.c +132 -0
  284. data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
  285. data/vendor/liburing/test/sqpoll-sleep.c +69 -0
  286. data/vendor/liburing/test/statx.c +172 -0
  287. data/vendor/liburing/test/stdout.c +232 -0
  288. data/vendor/liburing/test/submit-and-wait.c +108 -0
  289. data/vendor/liburing/test/submit-link-fail.c +156 -0
  290. data/vendor/liburing/test/submit-reuse.c +237 -0
  291. data/vendor/liburing/test/symlink.c +117 -0
  292. data/vendor/liburing/test/sync-cancel.c +235 -0
  293. data/vendor/liburing/test/teardowns.c +58 -0
  294. data/vendor/liburing/test/test.h +36 -0
  295. data/vendor/liburing/test/thread-exit.c +143 -0
  296. data/vendor/liburing/test/timeout-new.c +256 -0
  297. data/vendor/liburing/test/timeout.c +1798 -0
  298. data/vendor/liburing/test/truncate.c +186 -0
  299. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  300. data/vendor/liburing/test/unlink.c +112 -0
  301. data/vendor/liburing/test/version.c +25 -0
  302. data/vendor/liburing/test/wait-timeout.c +287 -0
  303. data/vendor/liburing/test/waitid.c +373 -0
  304. data/vendor/liburing/test/wakeup-hang.c +162 -0
  305. data/vendor/liburing/test/wq-aff.c +146 -0
  306. data/vendor/liburing/test/xattr.c +442 -0
  307. metadata +412 -0
@@ -0,0 +1,633 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test restrictions
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <fcntl.h>
12
+ #include <poll.h>
13
+ #include <sys/eventfd.h>
14
+
15
+ #include "liburing.h"
16
+
17
+ enum {
18
+ TEST_OK,
19
+ TEST_SKIPPED,
20
+ TEST_FAILED
21
+ };
22
+
23
+ static int test_restrictions_sqe_op(void)
24
+ {
25
+ struct io_uring_restriction res[2];
26
+ struct io_uring_sqe *sqe;
27
+ struct io_uring_cqe *cqe;
28
+ struct io_uring ring;
29
+ int ret, pipe1[2];
30
+
31
+ uint64_t ptr;
32
+ struct iovec vec = {
33
+ .iov_base = &ptr,
34
+ .iov_len = sizeof(ptr)
35
+ };
36
+
37
+ if (pipe(pipe1) != 0) {
38
+ perror("pipe");
39
+ return TEST_FAILED;
40
+ }
41
+
42
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
43
+ if (ret) {
44
+ if (ret == -EINVAL)
45
+ return TEST_SKIPPED;
46
+ fprintf(stderr, "ring setup failed: %d\n", ret);
47
+ return TEST_FAILED;
48
+ }
49
+
50
+ res[0].opcode = IORING_RESTRICTION_SQE_OP;
51
+ res[0].sqe_op = IORING_OP_WRITEV;
52
+
53
+ res[1].opcode = IORING_RESTRICTION_SQE_OP;
54
+ res[1].sqe_op = IORING_OP_WRITE;
55
+
56
+ ret = io_uring_register_restrictions(&ring, res, 2);
57
+ if (ret) {
58
+ if (ret == -EINVAL)
59
+ return TEST_SKIPPED;
60
+
61
+ fprintf(stderr, "failed to register restrictions: %d\n", ret);
62
+ return TEST_FAILED;
63
+ }
64
+
65
+ ret = io_uring_enable_rings(&ring);
66
+ if (ret) {
67
+ fprintf(stderr, "ring enabling failed: %d\n", ret);
68
+ return TEST_FAILED;
69
+ }
70
+
71
+ sqe = io_uring_get_sqe(&ring);
72
+ io_uring_prep_writev(sqe, pipe1[1], &vec, 1, 0);
73
+ sqe->user_data = 1;
74
+
75
+ sqe = io_uring_get_sqe(&ring);
76
+ io_uring_prep_readv(sqe, pipe1[0], &vec, 1, 0);
77
+ sqe->user_data = 2;
78
+
79
+ ret = io_uring_submit(&ring);
80
+ if (ret != 2) {
81
+ fprintf(stderr, "submit: %d\n", ret);
82
+ return TEST_FAILED;
83
+ }
84
+
85
+ for (int i = 0; i < 2; i++) {
86
+ ret = io_uring_wait_cqe(&ring, &cqe);
87
+ if (ret) {
88
+ fprintf(stderr, "wait: %d\n", ret);
89
+ return TEST_FAILED;
90
+ }
91
+
92
+ switch (cqe->user_data) {
93
+ case 1: /* writev */
94
+ if (cqe->res != sizeof(ptr)) {
95
+ fprintf(stderr, "write res: %d\n", cqe->res);
96
+ return TEST_FAILED;
97
+ }
98
+
99
+ break;
100
+ case 2: /* readv should be denied */
101
+ if (cqe->res != -EACCES) {
102
+ fprintf(stderr, "read res: %d\n", cqe->res);
103
+ return TEST_FAILED;
104
+ }
105
+ break;
106
+ }
107
+ io_uring_cqe_seen(&ring, cqe);
108
+ }
109
+
110
+ io_uring_queue_exit(&ring);
111
+ return TEST_OK;
112
+ }
113
+
114
+ static int test_restrictions_register_op(void)
115
+ {
116
+ struct io_uring_restriction res[1];
117
+ struct io_uring ring;
118
+ int ret, pipe1[2];
119
+
120
+ uint64_t ptr;
121
+ struct iovec vec = {
122
+ .iov_base = &ptr,
123
+ .iov_len = sizeof(ptr)
124
+ };
125
+
126
+ if (pipe(pipe1) != 0) {
127
+ perror("pipe");
128
+ return TEST_FAILED;
129
+ }
130
+
131
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
132
+ if (ret) {
133
+ fprintf(stderr, "ring setup failed: %d\n", ret);
134
+ return TEST_FAILED;
135
+ }
136
+
137
+ res[0].opcode = IORING_RESTRICTION_REGISTER_OP;
138
+ res[0].register_op = IORING_REGISTER_BUFFERS;
139
+
140
+ ret = io_uring_register_restrictions(&ring, res, 1);
141
+ if (ret) {
142
+ if (ret == -EINVAL)
143
+ return TEST_SKIPPED;
144
+
145
+ fprintf(stderr, "failed to register restrictions: %d\n", ret);
146
+ return TEST_FAILED;
147
+ }
148
+
149
+ ret = io_uring_enable_rings(&ring);
150
+ if (ret) {
151
+ fprintf(stderr, "ring enabling failed: %d\n", ret);
152
+ return TEST_FAILED;
153
+ }
154
+
155
+ ret = io_uring_register_buffers(&ring, &vec, 1);
156
+ if (ret) {
157
+ fprintf(stderr, "io_uring_register_buffers failed: %d\n", ret);
158
+ return TEST_FAILED;
159
+ }
160
+
161
+ ret = io_uring_register_files(&ring, pipe1, 2);
162
+ if (ret != -EACCES) {
163
+ fprintf(stderr, "io_uring_register_files ret: %d\n", ret);
164
+ return TEST_FAILED;
165
+ }
166
+
167
+ io_uring_queue_exit(&ring);
168
+ return TEST_OK;
169
+ }
170
+
171
+ static int test_restrictions_fixed_file(void)
172
+ {
173
+ struct io_uring_restriction res[4];
174
+ struct io_uring_sqe *sqe;
175
+ struct io_uring_cqe *cqe;
176
+ struct io_uring ring;
177
+ int ret, pipe1[2];
178
+
179
+ uint64_t ptr;
180
+ struct iovec vec = {
181
+ .iov_base = &ptr,
182
+ .iov_len = sizeof(ptr)
183
+ };
184
+
185
+ if (pipe(pipe1) != 0) {
186
+ perror("pipe");
187
+ return TEST_FAILED;
188
+ }
189
+
190
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
191
+ if (ret) {
192
+ fprintf(stderr, "ring setup failed: %d\n", ret);
193
+ return TEST_FAILED;
194
+ }
195
+
196
+ res[0].opcode = IORING_RESTRICTION_SQE_OP;
197
+ res[0].sqe_op = IORING_OP_WRITEV;
198
+
199
+ res[1].opcode = IORING_RESTRICTION_SQE_OP;
200
+ res[1].sqe_op = IORING_OP_READV;
201
+
202
+ res[2].opcode = IORING_RESTRICTION_SQE_FLAGS_REQUIRED;
203
+ res[2].sqe_flags = IOSQE_FIXED_FILE;
204
+
205
+ res[3].opcode = IORING_RESTRICTION_REGISTER_OP;
206
+ res[3].register_op = IORING_REGISTER_FILES;
207
+
208
+ ret = io_uring_register_restrictions(&ring, res, 4);
209
+ if (ret) {
210
+ if (ret == -EINVAL)
211
+ return TEST_SKIPPED;
212
+
213
+ fprintf(stderr, "failed to register restrictions: %d\n", ret);
214
+ return TEST_FAILED;
215
+ }
216
+
217
+ ret = io_uring_enable_rings(&ring);
218
+ if (ret) {
219
+ fprintf(stderr, "ring enabling failed: %d\n", ret);
220
+ return TEST_FAILED;
221
+ }
222
+
223
+ ret = io_uring_register_files(&ring, pipe1, 2);
224
+ if (ret) {
225
+ fprintf(stderr, "io_uring_register_files ret: %d\n", ret);
226
+ return TEST_FAILED;
227
+ }
228
+
229
+ sqe = io_uring_get_sqe(&ring);
230
+ io_uring_prep_writev(sqe, 1, &vec, 1, 0);
231
+ io_uring_sqe_set_flags(sqe, IOSQE_FIXED_FILE);
232
+ sqe->user_data = 1;
233
+
234
+ sqe = io_uring_get_sqe(&ring);
235
+ io_uring_prep_readv(sqe, 0, &vec, 1, 0);
236
+ io_uring_sqe_set_flags(sqe, IOSQE_FIXED_FILE);
237
+ sqe->user_data = 2;
238
+
239
+ sqe = io_uring_get_sqe(&ring);
240
+ io_uring_prep_writev(sqe, pipe1[1], &vec, 1, 0);
241
+ sqe->user_data = 3;
242
+
243
+ ret = io_uring_submit(&ring);
244
+ if (ret != 3) {
245
+ fprintf(stderr, "submit: %d\n", ret);
246
+ return TEST_FAILED;
247
+ }
248
+
249
+ for (int i = 0; i < 3; i++) {
250
+ ret = io_uring_wait_cqe(&ring, &cqe);
251
+ if (ret) {
252
+ fprintf(stderr, "wait: %d\n", ret);
253
+ return TEST_FAILED;
254
+ }
255
+
256
+ switch (cqe->user_data) {
257
+ case 1: /* writev */
258
+ if (cqe->res != sizeof(ptr)) {
259
+ fprintf(stderr, "write res: %d\n", cqe->res);
260
+ return TEST_FAILED;
261
+ }
262
+
263
+ break;
264
+ case 2: /* readv */
265
+ if (cqe->res != sizeof(ptr)) {
266
+ fprintf(stderr, "read res: %d\n", cqe->res);
267
+ return TEST_FAILED;
268
+ }
269
+ break;
270
+ case 3: /* writev without fixed_file should be denied */
271
+ if (cqe->res != -EACCES) {
272
+ fprintf(stderr, "write res: %d\n", cqe->res);
273
+ return TEST_FAILED;
274
+ }
275
+ break;
276
+ }
277
+ io_uring_cqe_seen(&ring, cqe);
278
+ }
279
+
280
+ io_uring_queue_exit(&ring);
281
+ return TEST_OK;
282
+ }
283
+
284
+ static int test_restrictions_flags(void)
285
+ {
286
+ struct io_uring_restriction res[3];
287
+ struct io_uring_sqe *sqe;
288
+ struct io_uring_cqe *cqe;
289
+ struct io_uring ring;
290
+ int ret, pipe1[2];
291
+
292
+ uint64_t ptr;
293
+ struct iovec vec = {
294
+ .iov_base = &ptr,
295
+ .iov_len = sizeof(ptr)
296
+ };
297
+
298
+ if (pipe(pipe1) != 0) {
299
+ perror("pipe");
300
+ return TEST_FAILED;
301
+ }
302
+
303
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
304
+ if (ret) {
305
+ fprintf(stderr, "ring setup failed: %d\n", ret);
306
+ return TEST_FAILED;
307
+ }
308
+
309
+ res[0].opcode = IORING_RESTRICTION_SQE_OP;
310
+ res[0].sqe_op = IORING_OP_WRITEV;
311
+
312
+ res[1].opcode = IORING_RESTRICTION_SQE_FLAGS_ALLOWED;
313
+ res[1].sqe_flags = IOSQE_ASYNC | IOSQE_IO_LINK;
314
+
315
+ res[2].opcode = IORING_RESTRICTION_SQE_FLAGS_REQUIRED;
316
+ res[2].sqe_flags = IOSQE_FIXED_FILE;
317
+
318
+ ret = io_uring_register_restrictions(&ring, res, 3);
319
+ if (ret) {
320
+ if (ret == -EINVAL)
321
+ return TEST_SKIPPED;
322
+
323
+ fprintf(stderr, "failed to register restrictions: %d\n", ret);
324
+ return TEST_FAILED;
325
+ }
326
+
327
+ ret = io_uring_register_files(&ring, pipe1, 2);
328
+ if (ret) {
329
+ fprintf(stderr, "io_uring_register_files ret: %d\n", ret);
330
+ return TEST_FAILED;
331
+ }
332
+
333
+ ret = io_uring_enable_rings(&ring);
334
+ if (ret) {
335
+ fprintf(stderr, "ring enabling failed: %d\n", ret);
336
+ return TEST_FAILED;
337
+ }
338
+
339
+ sqe = io_uring_get_sqe(&ring);
340
+ io_uring_prep_writev(sqe, 1, &vec, 1, 0);
341
+ io_uring_sqe_set_flags(sqe, IOSQE_FIXED_FILE);
342
+ sqe->user_data = 1;
343
+
344
+ sqe = io_uring_get_sqe(&ring);
345
+ io_uring_prep_writev(sqe, 1, &vec, 1, 0);
346
+ io_uring_sqe_set_flags(sqe, IOSQE_FIXED_FILE | IOSQE_ASYNC);
347
+ sqe->user_data = 2;
348
+
349
+ sqe = io_uring_get_sqe(&ring);
350
+ io_uring_prep_writev(sqe, 1, &vec, 1, 0);
351
+ io_uring_sqe_set_flags(sqe, IOSQE_FIXED_FILE | IOSQE_IO_LINK);
352
+ sqe->user_data = 3;
353
+
354
+ ret = io_uring_submit(&ring);
355
+ if (ret != 3) {
356
+ fprintf(stderr, "submit: %d\n", ret);
357
+ return TEST_FAILED;
358
+ }
359
+
360
+ sqe = io_uring_get_sqe(&ring);
361
+ io_uring_prep_writev(sqe, 1, &vec, 1, 0);
362
+ io_uring_sqe_set_flags(sqe, IOSQE_FIXED_FILE | IOSQE_IO_DRAIN);
363
+ sqe->user_data = 4;
364
+
365
+ ret = io_uring_submit(&ring);
366
+ if (ret != 1) {
367
+ fprintf(stderr, "submit: %d\n", ret);
368
+ return TEST_FAILED;
369
+ }
370
+
371
+ sqe = io_uring_get_sqe(&ring);
372
+ io_uring_prep_writev(sqe, pipe1[1], &vec, 1, 0);
373
+ io_uring_sqe_set_flags(sqe, IOSQE_IO_DRAIN);
374
+ sqe->user_data = 5;
375
+
376
+ ret = io_uring_submit(&ring);
377
+ if (ret != 1) {
378
+ fprintf(stderr, "submit: %d\n", ret);
379
+ return TEST_FAILED;
380
+ }
381
+
382
+ sqe = io_uring_get_sqe(&ring);
383
+ io_uring_prep_writev(sqe, pipe1[1], &vec, 1, 0);
384
+ io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
385
+ sqe->user_data = 6;
386
+
387
+ ret = io_uring_submit(&ring);
388
+ if (ret != 1) {
389
+ fprintf(stderr, "submit: %d\n", ret);
390
+ return TEST_FAILED;
391
+ }
392
+
393
+ sqe = io_uring_get_sqe(&ring);
394
+ io_uring_prep_writev(sqe, pipe1[1], &vec, 1, 0);
395
+ sqe->user_data = 7;
396
+
397
+ ret = io_uring_submit(&ring);
398
+ if (ret != 1) {
399
+ fprintf(stderr, "submit: %d\n", ret);
400
+ return TEST_FAILED;
401
+ }
402
+
403
+ for (int i = 0; i < 7; i++) {
404
+ ret = io_uring_wait_cqe(&ring, &cqe);
405
+ if (ret) {
406
+ fprintf(stderr, "wait: %d\n", ret);
407
+ return TEST_FAILED;
408
+ }
409
+
410
+ switch (cqe->user_data) {
411
+ case 1: /* writev - flags = IOSQE_FIXED_FILE */
412
+ case 2: /* writev - flags = IOSQE_FIXED_FILE | IOSQE_ASYNC */
413
+ case 3: /* writev - flags = IOSQE_FIXED_FILE | IOSQE_IO_LINK */
414
+ if (cqe->res != sizeof(ptr)) {
415
+ fprintf(stderr, "write res: %d user_data %" PRIu64 "\n",
416
+ cqe->res, (uint64_t) cqe->user_data);
417
+ return TEST_FAILED;
418
+ }
419
+
420
+ break;
421
+ case 4: /* writev - flags = IOSQE_FIXED_FILE | IOSQE_IO_DRAIN */
422
+ case 5: /* writev - flags = IOSQE_IO_DRAIN */
423
+ case 6: /* writev - flags = IOSQE_ASYNC */
424
+ case 7: /* writev - flags = 0 */
425
+ if (cqe->res != -EACCES) {
426
+ fprintf(stderr, "write res: %d user_data %" PRIu64 "\n",
427
+ cqe->res, (uint64_t) cqe->user_data);
428
+ return TEST_FAILED;
429
+ }
430
+ break;
431
+ }
432
+ io_uring_cqe_seen(&ring, cqe);
433
+ }
434
+
435
+ io_uring_queue_exit(&ring);
436
+ return TEST_OK;
437
+ }
438
+
439
+ static int test_restrictions_empty(void)
440
+ {
441
+ struct io_uring_restriction res[0];
442
+ struct io_uring_sqe *sqe;
443
+ struct io_uring_cqe *cqe;
444
+ struct io_uring ring;
445
+ int ret, pipe1[2];
446
+
447
+ uint64_t ptr;
448
+ struct iovec vec = {
449
+ .iov_base = &ptr,
450
+ .iov_len = sizeof(ptr)
451
+ };
452
+
453
+ if (pipe(pipe1) != 0) {
454
+ perror("pipe");
455
+ return TEST_FAILED;
456
+ }
457
+
458
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
459
+ if (ret) {
460
+ fprintf(stderr, "ring setup failed: %d\n", ret);
461
+ return TEST_FAILED;
462
+ }
463
+
464
+ ret = io_uring_register_restrictions(&ring, res, 0);
465
+ if (ret) {
466
+ if (ret == -EINVAL)
467
+ return TEST_SKIPPED;
468
+
469
+ fprintf(stderr, "failed to register restrictions: %d\n", ret);
470
+ return TEST_FAILED;
471
+ }
472
+
473
+ ret = io_uring_enable_rings(&ring);
474
+ if (ret) {
475
+ fprintf(stderr, "ring enabling failed: %d\n", ret);
476
+ return TEST_FAILED;
477
+ }
478
+
479
+ ret = io_uring_register_buffers(&ring, &vec, 1);
480
+ if (ret != -EACCES) {
481
+ fprintf(stderr, "io_uring_register_buffers ret: %d\n", ret);
482
+ return TEST_FAILED;
483
+ }
484
+
485
+ ret = io_uring_register_files(&ring, pipe1, 2);
486
+ if (ret != -EACCES) {
487
+ fprintf(stderr, "io_uring_register_files ret: %d\n", ret);
488
+ return TEST_FAILED;
489
+ }
490
+
491
+ sqe = io_uring_get_sqe(&ring);
492
+ io_uring_prep_writev(sqe, pipe1[1], &vec, 1, 0);
493
+
494
+ ret = io_uring_submit(&ring);
495
+ if (ret != 1) {
496
+ fprintf(stderr, "submit: %d\n", ret);
497
+ return TEST_FAILED;
498
+ }
499
+
500
+ ret = io_uring_wait_cqe(&ring, &cqe);
501
+ if (ret) {
502
+ fprintf(stderr, "wait: %d\n", ret);
503
+ return TEST_FAILED;
504
+ }
505
+
506
+ if (cqe->res != -EACCES) {
507
+ fprintf(stderr, "write res: %d\n", cqe->res);
508
+ return TEST_FAILED;
509
+ }
510
+
511
+ io_uring_cqe_seen(&ring, cqe);
512
+
513
+ io_uring_queue_exit(&ring);
514
+ return TEST_OK;
515
+ }
516
+
517
+ static int test_restrictions_rings_not_disabled(void)
518
+ {
519
+ struct io_uring_restriction res[1];
520
+ struct io_uring ring;
521
+ int ret;
522
+
523
+ ret = io_uring_queue_init(8, &ring, 0);
524
+ if (ret) {
525
+ fprintf(stderr, "ring setup failed: %d\n", ret);
526
+ return TEST_FAILED;
527
+ }
528
+
529
+ res[0].opcode = IORING_RESTRICTION_SQE_OP;
530
+ res[0].sqe_op = IORING_OP_WRITEV;
531
+
532
+ ret = io_uring_register_restrictions(&ring, res, 1);
533
+ if (ret != -EBADFD) {
534
+ fprintf(stderr, "io_uring_register_restrictions ret: %d\n",
535
+ ret);
536
+ return TEST_FAILED;
537
+ }
538
+
539
+ io_uring_queue_exit(&ring);
540
+ return TEST_OK;
541
+ }
542
+
543
+ static int test_restrictions_rings_disabled(void)
544
+ {
545
+ struct io_uring_sqe *sqe;
546
+ struct io_uring ring;
547
+ int ret;
548
+
549
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_R_DISABLED);
550
+ if (ret) {
551
+ fprintf(stderr, "ring setup failed: %d\n", ret);
552
+ return TEST_FAILED;
553
+ }
554
+
555
+ sqe = io_uring_get_sqe(&ring);
556
+ io_uring_prep_nop(sqe);
557
+
558
+ ret = io_uring_submit(&ring);
559
+ if (ret != -EBADFD) {
560
+ fprintf(stderr, "submit: %d\n", ret);
561
+ return TEST_FAILED;
562
+ }
563
+
564
+ io_uring_queue_exit(&ring);
565
+ return TEST_OK;
566
+ }
567
+
568
+ int main(int argc, char *argv[])
569
+ {
570
+ int ret;
571
+
572
+ if (argc > 1)
573
+ return 0;
574
+
575
+ ret = test_restrictions_sqe_op();
576
+ if (ret == TEST_SKIPPED) {
577
+ printf("test_restrictions_sqe_op: skipped\n");
578
+ return 0;
579
+ } else if (ret == TEST_FAILED) {
580
+ fprintf(stderr, "test_restrictions_sqe_op failed\n");
581
+ return ret;
582
+ }
583
+
584
+ ret = test_restrictions_register_op();
585
+ if (ret == TEST_SKIPPED) {
586
+ printf("test_restrictions_register_op: skipped\n");
587
+ } else if (ret == TEST_FAILED) {
588
+ fprintf(stderr, "test_restrictions_register_op failed\n");
589
+ return ret;
590
+ }
591
+
592
+ ret = test_restrictions_fixed_file();
593
+ if (ret == TEST_SKIPPED) {
594
+ printf("test_restrictions_fixed_file: skipped\n");
595
+ } else if (ret == TEST_FAILED) {
596
+ fprintf(stderr, "test_restrictions_fixed_file failed\n");
597
+ return ret;
598
+ }
599
+
600
+ ret = test_restrictions_flags();
601
+ if (ret == TEST_SKIPPED) {
602
+ printf("test_restrictions_flags: skipped\n");
603
+ } else if (ret == TEST_FAILED) {
604
+ fprintf(stderr, "test_restrictions_flags failed\n");
605
+ return ret;
606
+ }
607
+
608
+ ret = test_restrictions_empty();
609
+ if (ret == TEST_SKIPPED) {
610
+ printf("test_restrictions_empty: skipped\n");
611
+ } else if (ret == TEST_FAILED) {
612
+ fprintf(stderr, "test_restrictions_empty failed\n");
613
+ return ret;
614
+ }
615
+
616
+ ret = test_restrictions_rings_not_disabled();
617
+ if (ret == TEST_SKIPPED) {
618
+ printf("test_restrictions_rings_not_disabled: skipped\n");
619
+ } else if (ret == TEST_FAILED) {
620
+ fprintf(stderr, "test_restrictions_rings_not_disabled failed\n");
621
+ return ret;
622
+ }
623
+
624
+ ret = test_restrictions_rings_disabled();
625
+ if (ret == TEST_SKIPPED) {
626
+ printf("test_restrictions_rings_disabled: skipped\n");
627
+ } else if (ret == TEST_FAILED) {
628
+ fprintf(stderr, "test_restrictions_rings_disabled failed\n");
629
+ return ret;
630
+ }
631
+
632
+ return 0;
633
+ }