1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:27:45 +00:00

Add some basic setgroups(), getgroups() and initgroups().

Also teach /bin/id to print the user's supplemental groups.
This commit is contained in:
Andreas Kling 2018-11-07 01:38:51 +01:00
parent d3bd3791cb
commit a7f1d892a9
12 changed files with 167 additions and 19 deletions

View file

@ -21,6 +21,7 @@
//#define FORK_DEBUG
//#define SCHEDULER_DEBUG
#define COOL_GLOBALS
#define MAX_PROCESS_GIDS 32
#ifdef COOL_GLOBALS
struct CoolGlobals {
@ -304,7 +305,7 @@ int Process::exec(const String& path, Vector<String>&& arguments, Vector<String>
return error;
}
if (!handle->metadata().mayExecute(m_euid, m_egid))
if (!handle->metadata().mayExecute(m_euid, m_gids))
return -EACCES;
auto elfData = handle->readEntireFile();
@ -573,6 +574,8 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring
, m_tty(tty)
, m_ppid(ppid)
{
m_gids.set(m_gid);
if (fork_parent) {
m_sid = fork_parent->m_sid;
m_pgid = fork_parent->m_pgid;
@ -1566,3 +1569,33 @@ int Process::sys$sigaction(int signum, const Unix::sigaction* act, Unix::sigacti
action.handler_or_sigaction = LinearAddress((dword)act->sa_sigaction);
return 0;
}
int Process::sys$getgroups(int count, gid_t* gids)
{
if (count < 0)
return -EINVAL;
ASSERT(m_gids.size() < MAX_PROCESS_GIDS);
if (!count)
return m_gids.size();
if (count != m_gids.size())
return -EINVAL;
VALIDATE_USER_WRITE(gids, sizeof(gid_t) * count);
size_t i = 0;
for (auto gid : m_gids)
gids[i++] = gid;
return 0;
}
int Process::sys$setgroups(size_t count, const gid_t* gids)
{
if (!is_root())
return -EPERM;
if (count >= MAX_PROCESS_GIDS)
return -EINVAL;
VALIDATE_USER_READ(gids, sizeof(gid_t) * count);
m_gids.clear();
m_gids.set(m_gid);
for (size_t i = 0; i < count; ++i)
m_gids.set(gids[i]);
return 0;
}

View file

@ -139,6 +139,8 @@ public:
int sys$dup(int oldfd);
int sys$dup2(int oldfd, int newfd);
int sys$sigaction(int signum, const Unix::sigaction* act, Unix::sigaction* old_act);
int sys$getgroups(int size, gid_t*);
int sys$setgroups(size_t, const gid_t*);
static void initialize();
@ -177,6 +179,8 @@ public:
Process* fork(RegisterDump&);
int exec(const String& path, Vector<String>&& arguments, Vector<String>&& environment);
bool is_root() const { return m_euid == 0; }
private:
friend class MemoryManager;
friend bool scheduleNewProcess();
@ -242,6 +246,7 @@ private:
Vector<String> m_arguments;
Vector<String> m_initialEnvironment;
HashTable<gid_t> m_gids;
};
class ProcessInspectionScope {

View file

@ -152,6 +152,10 @@ static DWORD handle(RegisterDump& regs, DWORD function, DWORD arg1, DWORD arg2,
return current->sys$sigaction((int)arg1, (const Unix::sigaction*)arg2, (Unix::sigaction*)arg3);
case Syscall::SC_umask:
return current->sys$umask((mode_t)arg1);
case Syscall::SC_getgroups:
return current->sys$getgroups((int)arg1, (gid_t*)arg2);
case Syscall::SC_setgroups:
return current->sys$setgroups((size_t)arg1, (const gid_t*)arg2);
default:
kprintf("<%u> int0x80: Unknown function %x requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3);
break;

View file

@ -52,6 +52,8 @@
__ENUMERATE_SYSCALL(sigaction) \
__ENUMERATE_SYSCALL(getppid) \
__ENUMERATE_SYSCALL(umask) \
__ENUMERATE_SYSCALL(getgroups) \
__ENUMERATE_SYSCALL(setgroups) \
#define DO_SYSCALL_A0(function) Syscall::invoke((dword)(function))