]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
security: fix inverted user_range_ok checks in socket syscalls (M5)
authorTulio A M Mendes <[email protected]>
Thu, 11 Jun 2026 00:46:26 +0000 (21:46 -0300)
committerTulio A M Mendes <[email protected]>
Thu, 11 Jun 2026 00:46:26 +0000 (21:46 -0300)
- Fix SYSCALL_GETPEERNAME: user_range_ok == 0 means failure, not success
- Fix SYSCALL_GETSOCKNAME: user_range_ok == 0 means failure, not success
- Previously, the code incorrectly nested copy_to_user inside the
  user_range_ok == 0 check, which would only execute copy_to_user
  when the range check FAILED
- Now properly returns -EFAULT when user_range_ok fails, then
  calls copy_to_user when the range check succeeds

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 M5 from docs/URGENT_SECURITY_STATUS_2026-06-09.md

src/kernel/syscall.c

index 20271877f1e44866e9023df8ff4d1b4241e84273..a734210d8a9fbf2be5e9ee8f5e423f5bc2f2daff 100644 (file)
@@ -5432,9 +5432,10 @@ static void extended_syscall_dispatch(struct registers* regs, uint32_t syscall_n
         int r = ksocket_getpeername(sid, &sa);
         if (r == 0 && sc_arg1(regs)) {
             if (user_range_ok((void*)sc_arg1(regs), sizeof(sa)) == 0) {
-                if (copy_to_user((void*)sc_arg1(regs), &sa, sizeof(sa)) < 0) {
-                    sc_ret(regs) = (uint32_t)-EFAULT; return;
-                }
+                sc_ret(regs) = (uint32_t)-EFAULT; return;
+            }
+            if (copy_to_user((void*)sc_arg1(regs), &sa, sizeof(sa)) < 0) {
+                sc_ret(regs) = (uint32_t)-EFAULT; return;
             }
         }
         sc_ret(regs) = (uint32_t)r;
@@ -5449,9 +5450,10 @@ static void extended_syscall_dispatch(struct registers* regs, uint32_t syscall_n
         int r = ksocket_getsockname(sid, &sa);
         if (r == 0 && sc_arg1(regs)) {
             if (user_range_ok((void*)sc_arg1(regs), sizeof(sa)) == 0) {
-                if (copy_to_user((void*)sc_arg1(regs), &sa, sizeof(sa)) < 0) {
-                    sc_ret(regs) = (uint32_t)-EFAULT; return;
-                }
+                sc_ret(regs) = (uint32_t)-EFAULT; return;
+            }
+            if (copy_to_user((void*)sc_arg1(regs), &sa, sizeof(sa)) < 0) {
+                sc_ret(regs) = (uint32_t)-EFAULT; return;
             }
         }
         sc_ret(regs) = (uint32_t)r;