kernel+libc: Add support for supplementary groups (2/2)
Adds system calls for setting and getting groups, along with libc wrappers.
This commit is contained in:
parent
3ad23eab21
commit
8a90db837b
@ -9,7 +9,7 @@
|
||||
_e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(sigprocmask) _e(setpgid) _e(isatty) \
|
||||
_e(getpgid) _e(socket) _e(bind) _e(connect) _e(listen) _e(accept) _e(poll) _e(msync) \
|
||||
_e(truncate) _e(ftruncate) _e(utimensat) _e(setitimer) _e(pledge) _e(memstat) \
|
||||
_e(setsid) _e(getsid)
|
||||
_e(setsid) _e(getsid) _e(getgroups) _e(setgroups)
|
||||
|
||||
enum Syscalls
|
||||
{
|
||||
|
@ -237,3 +237,54 @@ Result<u64> sys_fchownat(Registers*, SyscallArgs args)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result<u64> sys_getgroups(Registers*, SyscallArgs args)
|
||||
{
|
||||
int ngroups = (int)args[0];
|
||||
gid_t* grouplist = (gid_t*)args[1];
|
||||
|
||||
auto* current = Scheduler::current();
|
||||
|
||||
TRY(check_pledge(current, Promise::p_stdio));
|
||||
|
||||
if (!ngroups) return current->extra_groups.size();
|
||||
if (ngroups < 0) return err(EINVAL);
|
||||
|
||||
if (static_cast<usize>(ngroups) < current->extra_groups.size()) return err(EINVAL);
|
||||
|
||||
if (!MemoryManager::copy_to_user(grouplist, current->extra_groups.data(),
|
||||
current->extra_groups.size() * sizeof(gid_t)))
|
||||
return err(EFAULT);
|
||||
|
||||
return current->extra_groups.size();
|
||||
}
|
||||
|
||||
Result<u64> sys_setgroups(Registers*, SyscallArgs args)
|
||||
{
|
||||
int ngroups = (int)args[0];
|
||||
const gid_t* grouplist = (const gid_t*)args[1];
|
||||
|
||||
auto* current = Scheduler::current();
|
||||
|
||||
TRY(check_pledge(current, Promise::p_id));
|
||||
|
||||
Credentials& auth = current->auth;
|
||||
if (auth.euid != 0) return err(EPERM);
|
||||
|
||||
if (!ngroups)
|
||||
{
|
||||
current->extra_groups.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ngroups < 0 || ngroups > 32) return err(EINVAL);
|
||||
|
||||
TRY(current->extra_groups.try_reserve(ngroups));
|
||||
|
||||
current->extra_groups.mutate([&](gid_t* list, usize) -> usize {
|
||||
if (MemoryManager::copy_from_user(grouplist, list, ngroups * sizeof(gid_t))) return ngroups;
|
||||
return current->extra_groups.size();
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ extern "C"
|
||||
/* End group file parsing. */
|
||||
void endgrent(void);
|
||||
|
||||
/* Set this process's list of supplementary groups. */
|
||||
int setgroups(int size, const gid_t* list);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -205,6 +205,9 @@ extern "C"
|
||||
/* Restrict system operations. */
|
||||
int pledge(const char* promises, const char* execpromises);
|
||||
|
||||
/* Get this process's list of supplementary groups. */
|
||||
int getgroups(int size, gid_t* list);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <luna/Vector.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static struct group grp;
|
||||
static FILE* f { nullptr };
|
||||
@ -112,4 +114,10 @@ extern "C"
|
||||
f = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int setgroups(int size, const gid_t* list)
|
||||
{
|
||||
long rc = syscall(SYS_setgroups, size, list);
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
}
|
||||
|
@ -545,4 +545,10 @@ extern "C"
|
||||
long rc = syscall(SYS_setsid);
|
||||
__errno_return(rc, pid_t);
|
||||
}
|
||||
|
||||
int getgroups(int size, gid_t* list)
|
||||
{
|
||||
long rc = syscall(SYS_getgroups, size, list);
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <luna/Alloc.h>
|
||||
#include <luna/CString.h>
|
||||
#include <luna/Common.h>
|
||||
#include <luna/Result.h>
|
||||
#include <luna/Slice.h>
|
||||
#include <luna/Types.h>
|
||||
@ -245,6 +246,12 @@ template <typename T> class Vector
|
||||
return other;
|
||||
}
|
||||
|
||||
template <typename Callback> void mutate(Callback callback)
|
||||
{
|
||||
usize size = callback(m_data, m_capacity);
|
||||
m_size = min(m_capacity, size);
|
||||
}
|
||||
|
||||
private:
|
||||
T* m_data { nullptr };
|
||||
usize m_capacity { 0 };
|
||||
|
Loading…
Reference in New Issue
Block a user