COPY(9)

πŸ’– COPY(9) β€” kernel copy functions πŸ’–

okay bestie so this is COPY(9) from the Kernel Developer's Manual, and it's literally the page that explains how the kernel moves bytes around without touching the wrong memory and having a whole existential crisis. It's giving essential infrastructure. πŸ¦‹


✨ NAME ✨

copy, copyin, copyin_nofault, copyout, copyout_nofault, copystr, copyinstr β€” the kernel copy functions, aka the friend group that carries your data across the user/kernel boundary 🫢


🌸 SYNOPSIS 🌸

#include <sys/types.h>
#include <sys/systm.h>

int
copyin(const void *uaddr, void *kaddr, size_t len);

int
copyin_nofault(const void *uaddr, void *kaddr, size_t len);

int
copyout(const void *kaddr, void *uaddr, size_t len);

int
copyout_nofault(const void *kaddr, void *uaddr, size_t len);

int
copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done);

int
copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done);

πŸ’… DESCRIPTION πŸ’…

So the copy functions are all about copying contiguous data from one address to another. That's the whole vibe. ✨

And all of them except copystr() move data from user-space to kernel-space, or the other way around. The two worlds, holding hands. 🫢

  • copyin() and copyin_nofault() copy len bytes of data from the user-space address uaddr to the kernel-space address kaddr. Bringing it home. 🏠
  • copyout() and copyout_nofault() copy len bytes of data from the kernel-space address kaddr to the user-space address uaddr. Sending it out into the world. πŸ¦‹
  • copyin_nofault() and copyout_nofault() have a strict requirement bestie, no cap: the kernel-space and user-space data must be accessible without incurring a page fault. The source and destination addresses must be physically mapped for read and write access respectively, and neither the source nor the destination addresses may be pageable. So like, they have to be right there, ready, no dramatics. πŸ’€
  • copystr() copies a NUL-terminated string, at most len bytes long, from the kernel-space address kfaddr to the kernel-space address kdaddr. The number of bytes actually copied β€” including the terminating NUL β€” gets returned in *done (if done is non-NULL, obviously, don't be handing it a NULL and expecting magic). πŸŽ€
  • copyinstr() copies a NUL-terminated string, at most len bytes long, from the user-space address uaddr to the kernel-space address kaddr. Same deal: the number of bytes actually copied, including the terminating NUL, comes back in *done (if done is non-NULL). ⭐

πŸ”₯ RETURN VALUES πŸ”₯

The copy functions return 0 on success. Iconic. We love a zero. πŸ‘‘

All of them except copystr() return EFAULT if a bad address is encountered β€” like, the address said it was fine and then it was not fine. 😭

copyin_nofault() and copyout_nofault() return EFAULT if a page fault occurs. Which, reminder, is exactly the thing they cannot handle. πŸ™ˆ

copystr() and copyinstr() return ENAMETOOLONG if the string is longer than len bytes. Too much string. Excessive. The string ate and there's nothing left. πŸ’€


πŸ¦‹ SEE ALSO πŸ¦‹


okay that's the whole page bestie, you're basically a kernel dev now, mwah πŸ’…βœ¨

This one came from the Debian crew, dated June 15, 2017, and honestly? Still serving. COPY(9) out. πŸŽ€πŸ’–πŸŒŸ

πŸ“¦ where this page comes from