FETCH(9)

🌸 FETCH β€” from the Kernel Developer's Manual, section 9 🌸

okay bestie, buckle up, we're going into kernel-space and we're gonna fetch stuff from user-space πŸ’… this is the fetch family: fetch, fubyte, fuword, fuword16, fuword32, fuword64, fueword, fueword32, fueword64 β€” they fetch data from user-space, and they are lowkey iconic for it 🫢


✨ SYNOPSIS ✨

no cap, the includes come in two waves. first these:

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

and then the whole girlband of signatures πŸŽ€

int
fubyte(volatile const void *base);

long
fuword(volatile const void *base);

int
fuword16(volatile const void *base);

int32_t
fuword32(volatile const void *base);

int64_t
fuword64(volatile const void *base);

int
fueword(volatile const void *base, long *val);

int
fueword32(volatile const void *base, int32_t *val);

int
fueword64(volatile const void *base, int64_t *val);

and then, plot twist, another include shows up fashionably late πŸ’–

#include <sys/resourcevar.h>

πŸ’– DESCRIPTION πŸ’–

so the fetch functions are literally designed to copy small amounts of data from the user-space of the current process. that's the whole vibe. and if the read is successful, it is performed atomically β€” yes ma'am, no half-reads, we do not do partial here ✨

one thing though, and this is the main character rule: the data read must be naturally aligned. not aligned? don't talk to me πŸ™ˆ

the fetch routines each serve a different little purpose, and here's the full lineup, no skips:

  • fubyte() β€” fetches a byte of data from the user-space address base. the byte read is zero-extended into the results variable. tiny but mighty πŸ“
  • fuword() β€” fetches a word of data (long) from the user-space address base.
  • fuword16() β€” fetches 16 bits of data from the user-space address base. the half-word read is zero-extended into the results variable.
  • fuword32() β€” fetches 32 bits of data from the user-space address base.
  • fuword64() β€” fetches 64 bits of data from the user-space address base.
  • fueword() β€” fetches a word of data (long) from the user-space address base and stores the result in the variable pointed to by val.
  • fueword32() β€” fetches 32 bits of data from the user-space address base and stores the result in the variable pointed to by val.
  • fueword64() β€” fetches 64 bits of data from the user-space address base and stores the result in the variable pointed to by val.
⚠️ okay so this part is important and also a little cursed: the callers of fuword(), fuword32() and fuword64() cannot distinguish between -1 read from userspace and function failure. like, a real -1 and a broken -1 look exactly the same. it's giving identity theft πŸ’€

🌈 RETURN VALUES 🌈

here's the receipts:

  • fubyte(), fuword(), fuword16(), fuword32(), and fuword64() return the data fetched, or -1 on failure.
  • fueword(), fueword32() and fueword64() return 0 on success and -1 on failure.

periodt πŸ’…


πŸ‘‘ SEE ALSO πŸ‘‘

go read these next bestie, they're in the same friend group:


and that's the whole page, you ate it 🫢 this was the FETCH(9) page from Debian, dated January 23, 2020 β€” mwah, iconic, tysm for reading, ily, go align your data πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from