summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-10-05 19:13:44 -0400
committerIan Moffett <ian@osmora.org>2025-10-05 19:13:44 -0400
commit2e42d32407165f437549abddd319f8feab0051d6 (patch)
treef123df6adff5b8dfa01e82e0141f413461ffc05e /src
parentb7ed37d5af4bdf78f2fbed4af896e9956bc85168 (diff)
kern: os: Add copyinstr()
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src')
-rw-r--r--src/sys/include/os/systm.h12
-rw-r--r--src/sys/os/os_systm.c26
2 files changed, 38 insertions, 0 deletions
diff --git a/src/sys/include/os/systm.h b/src/sys/include/os/systm.h
index 33de08a..24f21db 100644
--- a/src/sys/include/os/systm.h
+++ b/src/sys/include/os/systm.h
@@ -33,6 +33,18 @@
#include <sys/types.h>
/*
+ * Copy userland string to kernel space safely
+ *
+ * @uaddr: Userspace source address to copy from
+ * @kaddr: Kernel address dest address to copy to
+ * @len: Length of buffer
+ *
+ * Returns 0 on success, otherwise a less than zero value
+ * on failure.
+ */
+int copyinstr(const void *uaddr, char *kaddr, size_t len);
+
+/*
* Copy userland data to kernel space safely
*
* @uaddr: Userspace source address to copy from
diff --git a/src/sys/os/os_systm.c b/src/sys/os/os_systm.c
index f7fd8f1..69fab30 100644
--- a/src/sys/os/os_systm.c
+++ b/src/sys/os/os_systm.c
@@ -91,3 +91,29 @@ copyout(const void *kaddr, void *uaddr, size_t len)
memcpy(uaddr, kaddr, len);
return 0;
}
+
+int
+copyinstr(const void *uaddr, char *kaddr, size_t len)
+{
+ char *dest = (char *)kaddr;
+ const char *src = (char *)uaddr;
+ char dmmy;
+
+ if (copyin(uaddr, &dmmy, 1) != 0) {
+ return -EFAULT;
+ }
+
+ for (size_t i = 0; i < len; ++i) {
+ if (copyin(uaddr + i, &dmmy, 1) != 0) {
+ return -EFAULT;
+ }
+
+ dest[i] = src[i];
+
+ if (src[i] == '\0') {
+ break;
+ }
+ }
+
+ return 0;
+}