This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 49e69a7e6b2534eb621425b055a52b9d55d7a87f
Author: Royyan Zahir <[email protected]>
AuthorDate: Wed Sep 30 09:24:26 2026 +0400

    sched/addrenv: check that a pointer from user space is user memory
    
    uaccess_ok() says whether a range lies in the caller's address
    environment and uaccess_check() kills the caller when it does not. They
    are how a kernel build refuses a kernel address passed in by a process.
    
    Signed-off-by: Royyan Zahir <[email protected]>
---
 include/nuttx/addrenv.h | 16 ++++++++++++++++
 sched/addrenv/addrenv.c | 27 +++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/include/nuttx/addrenv.h b/include/nuttx/addrenv.h
index 4c479fe511e..bfd8a841840 100644
--- a/include/nuttx/addrenv.h
+++ b/include/nuttx/addrenv.h
@@ -36,6 +36,7 @@
 #endif
 
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
 
 #include <nuttx/atomic.h>
@@ -322,6 +323,11 @@ struct addrenv_reserve_s
  * Public Function Prototypes
  ****************************************************************************/
 
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
 /****************************************************************************
  * Name: addrenv_allocate
  *
@@ -532,6 +538,16 @@ int addrenv_give(FAR struct addrenv_s *addrenv);
 
 void addrenv_drop(FAR struct addrenv_s *addrenv, bool deferred);
 
+#ifdef CONFIG_BUILD_KERNEL
+bool uaccess_ok(FAR const void *ptr, size_t len);
+void uaccess_check(FAR const void *ptr, size_t len);
+void uaccess_fault(FAR const void *ptr) noreturn_function;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 /****************************************************************************
  * Address Environment Interfaces
  *
diff --git a/sched/addrenv/addrenv.c b/sched/addrenv/addrenv.c
index 66afa48dcda..514ae1a5291 100644
--- a/sched/addrenv/addrenv.c
+++ b/sched/addrenv/addrenv.c
@@ -29,6 +29,8 @@
 #include <assert.h>
 #include <errno.h>
 #include <nuttx/debug.h>
+#include <signal.h>
+#include <unistd.h>
 
 #include <nuttx/addrenv.h>
 #include <nuttx/atomic.h>
@@ -548,3 +550,28 @@ void addrenv_drop(FAR struct addrenv_s *addrenv, bool 
deferred)
         }
     }
 }
+
+#ifdef CONFIG_BUILD_KERNEL
+bool uaccess_ok(FAR const void *ptr, size_t len)
+{
+  uintptr_t start = (uintptr_t)ptr;
+  uintptr_t end = start + len - 1;
+
+  return up_addrenv_user_vaddr(start) &&
+         (len == 0 || (end >= start && up_addrenv_user_vaddr(end)));
+}
+
+void uaccess_check(FAR const void *ptr, size_t len)
+{
+  if (!uaccess_ok(ptr, len))
+    {
+      uaccess_fault(ptr);
+    }
+}
+
+void uaccess_fault(FAR const void *ptr)
+{
+  _alert("%s: %p is not user memory\n", get_task_name(this_task()), ptr);
+  _exit(SIGSEGV);
+}
+#endif

Reply via email to