diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-09-20 15:38:06 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-09-20 15:38:06 +0300 |
| commit | d2f2714398d415eb9a628aab82b332b92ad5c923 (patch) | |
| tree | ce6844c3f6f446b3acefffbd294dfecd3eb8dc98 /common/uapi/cap.c | |
| parent | a717296a2036cede5fccfff544513043a984d614 (diff) | |
| download | kmi-d2f2714398d415eb9a628aab82b332b92ad5c923.tar.gz kmi-d2f2714398d415eb9a628aab82b332b92ad5c923.zip | |
add capability subsystem and syscalls
Diffstat (limited to 'common/uapi/cap.c')
| -rw-r--r-- | common/uapi/cap.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/common/uapi/cap.c b/common/uapi/cap.c new file mode 100644 index 0000000..84dbc45 --- /dev/null +++ b/common/uapi/cap.c @@ -0,0 +1,87 @@ +#include <apos/uapi.h> +#include <apos/caps.h> +#include <apos/tcb.h> + +/** + * @file cap.c + * Sycalls handlers for thread capabilities. + */ + +/** + * Check that values are legal for thread ID and offset. + * + * @param tid Thread ID of thread whose caps should be fetched. + * @param off Offset of capabilities. + * @return Pointer to capabilities of \p tid, \c 0 otherwise. + */ +static capflags_t *__get_tcb_caps(id_t tid, size_t off) +{ + if (!cap_off_ok(off)) + return NULL; + + struct tcb *t = get_tcb(tid); + if (!t) + return NULL; + + return &t->caps; +} + +/** + * Set capabilities. + * + * @param tid Thread ID whose capabilities to set. + * @param off Offset of capability, multiple of \c bits(cap). + * @param caps Mask of capabilities to set. + * @return \ref OK on success, \ref ERR_INVAL on invalid input. + */ +SYSCALL_DEFINE3(set_cap)(sys_arg_t tid, sys_arg_t off, sys_arg_t caps) +{ + struct tcb *t = cur_tcb(); + if (!is_set(t->caps, CAP_CAPS)) + return (struct sys_ret){ERR_PERM, 0, 0, 0, 0, 0}; + + capflags_t *c; + if (!(c = __get_tcb_caps(tid, off))) + return (struct sys_ret){ERR_INVAL, 0, 0, 0, 0, 0}; + + set_caps(*c, off, caps); + return (struct sys_ret){OK, 0, 0, 0, 0, 0}; +} + +/** + * Get capabilities. + * + * @param tid Thread ID whose capabilities to get. + * @param off Offset of capability, multiple of \c bits(cap). + * @return \ref OK, capabilities. + */ +SYSCALL_DEFINE2(get_cap)(sys_arg_t tid, sys_arg_t off) +{ + capflags_t *c; + if (!(c = __get_tcb_caps(tid, off))) + return (struct sys_ret){ERR_INVAL, 0, 0, 0, 0, 0}; + + return (struct sys_ret){OK, get_caps(*c, off), 0, 0, 0, 0}; +} + +/** + * Clear capabilities. + * + * @param tid Thread ID whose capabilities to clear. + * @param off Offset of capability, multiple of \c bits(cap). + * @param caps Mask of capabilities to clear. + * @return \ref OK. + */ +SYSCALL_DEFINE3(clear_cap)(sys_arg_t tid, sys_arg_t off, sys_arg_t caps) +{ + struct tcb *t = cur_tcb(); + if (!is_set(t->caps, CAP_CAPS)) + return (struct sys_ret){ERR_PERM, 0, 0, 0, 0, 0}; + + capflags_t *c; + if (!(c = __get_tcb_caps(tid, off))) + return (struct sys_ret){ERR_INVAL, 0, 0, 0, 0, 0}; + + clear_caps(*c, off, caps); + return (struct sys_ret){OK, 0, 0, 0, 0, 0}; +} |
