mirror of
https://github.com/RGBCube/serenity
synced 2025-07-10 04:37:35 +00:00
UserspaceEmulator: Implement enough syscalls to get /bin/id running :^)
This commit is contained in:
parent
1b196df4c4
commit
95a42efc62
2 changed files with 78 additions and 1 deletions
|
@ -29,6 +29,7 @@
|
||||||
#include <AK/LexicalPath.h>
|
#include <AK/LexicalPath.h>
|
||||||
#include <AK/LogStream.h>
|
#include <AK/LogStream.h>
|
||||||
#include <Kernel/API/Syscall.h>
|
#include <Kernel/API/Syscall.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
@ -223,6 +224,8 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
|
||||||
return virt$mmap(arg1);
|
return virt$mmap(arg1);
|
||||||
case SC_gettid:
|
case SC_gettid:
|
||||||
return virt$gettid();
|
return virt$gettid();
|
||||||
|
case SC_getpid:
|
||||||
|
return virt$getpid();
|
||||||
case SC_pledge:
|
case SC_pledge:
|
||||||
return virt$pledge(arg1);
|
return virt$pledge(arg1);
|
||||||
case SC_unveil:
|
case SC_unveil:
|
||||||
|
@ -231,6 +234,8 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
|
||||||
return virt$getuid();
|
return virt$getuid();
|
||||||
case SC_getgid:
|
case SC_getgid:
|
||||||
return virt$getgid();
|
return virt$getgid();
|
||||||
|
case SC_close:
|
||||||
|
return virt$close(arg1);
|
||||||
case SC_write:
|
case SC_write:
|
||||||
return virt$write(arg1, arg2, arg3);
|
return virt$write(arg1, arg2, arg3);
|
||||||
case SC_read:
|
case SC_read:
|
||||||
|
@ -239,6 +244,14 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
|
||||||
return virt$mprotect(arg1, arg2, arg3);
|
return virt$mprotect(arg1, arg2, arg3);
|
||||||
case SC_madvise:
|
case SC_madvise:
|
||||||
return virt$madvise(arg1, arg2, arg3);
|
return virt$madvise(arg1, arg2, arg3);
|
||||||
|
case SC_open:
|
||||||
|
return virt$open(arg1);
|
||||||
|
case SC_fcntl:
|
||||||
|
return virt$fcntl(arg1, arg2, arg3);
|
||||||
|
case SC_getgroups:
|
||||||
|
return virt$getgroups(arg1, arg2);
|
||||||
|
case SC_lseek:
|
||||||
|
return virt$lseek(arg1, arg2, arg3);
|
||||||
case SC_exit:
|
case SC_exit:
|
||||||
virt$exit((int)arg1);
|
virt$exit((int)arg1);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -249,6 +262,59 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Emulator::virt$close(int fd)
|
||||||
|
{
|
||||||
|
return syscall(SC_close, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Emulator::virt$lseek(int fd, off_t offset, int whence)
|
||||||
|
{
|
||||||
|
return syscall(SC_lseek, fd, offset, whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Emulator::virt$getgroups(ssize_t count, FlatPtr groups)
|
||||||
|
{
|
||||||
|
if (!count)
|
||||||
|
return syscall(SC_getgroups, 0, nullptr);
|
||||||
|
|
||||||
|
auto buffer = ByteBuffer::create_uninitialized(count * sizeof(gid_t));
|
||||||
|
int rc = syscall(SC_getgroups, count, buffer.data());
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
mmu().copy_to_vm(groups, buffer.data(), buffer.size());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Emulator::virt$fcntl(int fd, int cmd, u32 arg)
|
||||||
|
{
|
||||||
|
switch (cmd) {
|
||||||
|
case F_DUPFD:
|
||||||
|
case F_GETFD:
|
||||||
|
case F_SETFD:
|
||||||
|
case F_GETFL:
|
||||||
|
case F_SETFL:
|
||||||
|
case F_ISTTY:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TODO();
|
||||||
|
}
|
||||||
|
|
||||||
|
return syscall(SC_fcntl, fd, cmd, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Emulator::virt$open(u32 params_addr)
|
||||||
|
{
|
||||||
|
Syscall::SC_open_params params;
|
||||||
|
mmu().copy_from_vm(¶ms, params_addr, sizeof(params));
|
||||||
|
|
||||||
|
auto path = mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length);
|
||||||
|
|
||||||
|
int fd = openat_with_path_length(params.dirfd, (const char*)path.data(), path.size(), params.options, params.mode);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
u32 Emulator::virt$mmap(u32 params_addr)
|
u32 Emulator::virt$mmap(u32 params_addr)
|
||||||
{
|
{
|
||||||
Syscall::SC_mmap_params params;
|
Syscall::SC_mmap_params params;
|
||||||
|
@ -282,6 +348,11 @@ u32 Emulator::virt$gettid()
|
||||||
return gettid();
|
return gettid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 Emulator::virt$getpid()
|
||||||
|
{
|
||||||
|
return getpid();
|
||||||
|
}
|
||||||
|
|
||||||
u32 Emulator::virt$pledge(u32)
|
u32 Emulator::virt$pledge(u32)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -307,7 +378,7 @@ uid_t Emulator::virt$getuid()
|
||||||
return getuid();
|
return getuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
uid_t Emulator::virt$getgid()
|
gid_t Emulator::virt$getgid()
|
||||||
{
|
{
|
||||||
return getgid();
|
return getgid();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ private:
|
||||||
|
|
||||||
u32 virt$mmap(u32);
|
u32 virt$mmap(u32);
|
||||||
u32 virt$gettid();
|
u32 virt$gettid();
|
||||||
|
u32 virt$getpid();
|
||||||
u32 virt$unveil(u32);
|
u32 virt$unveil(u32);
|
||||||
u32 virt$pledge(u32);
|
u32 virt$pledge(u32);
|
||||||
uid_t virt$getuid();
|
uid_t virt$getuid();
|
||||||
|
@ -65,6 +66,11 @@ private:
|
||||||
u32 virt$write(int, FlatPtr, ssize_t);
|
u32 virt$write(int, FlatPtr, ssize_t);
|
||||||
u32 virt$mprotect(FlatPtr, size_t, int);
|
u32 virt$mprotect(FlatPtr, size_t, int);
|
||||||
u32 virt$madvise(FlatPtr, size_t, int);
|
u32 virt$madvise(FlatPtr, size_t, int);
|
||||||
|
u32 virt$open(u32);
|
||||||
|
int virt$close(int);
|
||||||
|
u32 virt$fcntl(int fd, int, u32);
|
||||||
|
int virt$getgroups(ssize_t count, FlatPtr);
|
||||||
|
int virt$lseek(int fd, off_t offset, int whence);
|
||||||
void virt$exit(int);
|
void virt$exit(int);
|
||||||
|
|
||||||
bool m_shutdown { false };
|
bool m_shutdown { false };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue