diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-26 14:51:51 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-26 14:51:51 -0400 |
commit | d267fcf7b8c8d53a2d1807570c278cf39727eb16 (patch) | |
tree | f725b9bce35a4c9b0cf7546235fd9c9cf3297f85 /sys/kern/kern_subr.c | |
parent | add3e844cf9eaf49010fbee2aa73977086e47428 (diff) |
kernel: Add copyinstr() routine
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/kern/kern_subr.c')
-rw-r--r-- | sys/kern/kern_subr.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c index dd1a618..d9b1b3a 100644 --- a/sys/kern/kern_subr.c +++ b/sys/kern/kern_subr.c @@ -93,3 +93,42 @@ copyout(const void *kaddr, uintptr_t uaddr, size_t len) memcpy((void *)uaddr, kaddr, len); return 0; } + +/* + * Copy in a string from userspace + * + * Unlike the typical copyin(), this routine will + * copy until we've hit NUL ('\0') + * + * @uaddr: Userspace address. + * @kaddr: Kernelspace address. + * @len: Length of string. + * + * XXX: Please note that if `len' is less than the actual + * string length, the returned value will not be + * NUL terminated. + */ +int +copyinstr(uintptr_t uaddr, char *kaddr, size_t len) +{ + char *dest = (char *)kaddr; + char *src = (char *)uaddr; + + if (!check_uaddr(uaddr)) { + return -EFAULT; + } + + for (size_t i = 0; i < len; ++i) { + if (!check_uaddr(uaddr + i)) { + return -EFAULT; + } + + dest[i] = src[i]; + + if (src[i] == '\0') { + break; + } + } + + return 0; +} |