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:
parent
d3bd3791cb
commit
a7f1d892a9
12 changed files with 167 additions and 19 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue