]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
security: complete AIO validation (H1)
authorTulio A M Mendes <[email protected]>
Thu, 11 Jun 2026 00:44:47 +0000 (21:44 -0300)
committerTulio A M Mendes <[email protected]>
Thu, 11 Jun 2026 00:44:47 +0000 (21:44 -0300)
- Add fd mode validation in syscall_aio_rw_impl:
  - Reject aio_read on O_WRONLY fd (except char devices)
  - Reject aio_write on O_RDONLY fd (except char devices)
  - Reject aio_write on MS_RDONLY mount
- Reuse same policy as read/write/pread/pwrite syscalls
- Fix fulltest AIO test to use O_RDWR instead of O_WRONLY
  (test was incorrectly trying to read from write-only fd)

Validation:
- make -j12: PASS
- make test-host: PASS (111/111)
- make test SMOKE_SMP=4: PASS (127/127)
- make test-battery: PASS (153/153)
- make analyzer: PASS

Addresses H1 from docs/URGENT_SECURITY_STATUS_2026-06-09.md

src/kernel/syscall.c
user/cmds/fulltest/fulltest.c

index e23a3772d4d47db1a484f08918d0d1f13638605c..20271877f1e44866e9023df8ff4d1b4241e84273 100644 (file)
@@ -1614,6 +1614,30 @@ static int syscall_aio_rw_impl(void* user_cb, int is_write) {
         return 0;
     }
 
+    /* H1: reject aio_read on O_WRONLY fd (except char devices) */
+    if (!is_write && (f->flags & 3U) == 1U && f->node->flags != FS_CHARDEVICE) {
+        cb.aio_error = EBADF;
+        cb.aio_return = -EBADF;
+        (void)copy_to_user(user_cb, &cb, sizeof(cb));
+        return 0;
+    }
+
+    /* H1: reject aio_write on O_RDONLY fd (except char devices) */
+    if (is_write && (f->flags & 3U) == 0U && f->node->flags != FS_CHARDEVICE) {
+        cb.aio_error = EBADF;
+        cb.aio_return = -EBADF;
+        (void)copy_to_user(user_cb, &cb, sizeof(cb));
+        return 0;
+    }
+
+    /* H1: reject aio_write on MS_RDONLY mount */
+    if (is_write && f->mount_root && (vfs_node_mount_flags(f->mount_root) & MS_RDONLY)) {
+        cb.aio_error = EROFS;
+        cb.aio_return = -EROFS;
+        (void)copy_to_user(user_cb, &cb, sizeof(cb));
+        return 0;
+    }
+
     if (!cb.aio_buf || cb.aio_nbytes == 0) {
         cb.aio_error = 0;
         cb.aio_return = 0;
index ee539588442c93f4c45e290a0ed948e211d74c03..a0dfe2dbb0c7e0a0dc9955a61c6a3f169688e5d9 100644 (file)
@@ -3558,7 +3558,7 @@ void _start(void) {
 
     // C24: aio_read/aio_write smoke
     {
-        int fd = sys_open("/tmp/aiotest", O_CREAT | O_TRUNC | 1);
+        int fd = sys_open("/tmp/aiotest", O_CREAT | O_TRUNC | 2);
         if (fd < 0) {
             sys_write(1, "[test] aio open failed\n", (uint32_t)(sizeof("[test] aio open failed\n") - 1));
             sys_exit(1);