base-linux: avoid legacy syscalls

Until now, Genode's Linux system call bindings were based on original
Unix system calls that were later superseded by more flexibile variants.
E.g., 'openat' is a modern version of 'open'. Even though Linux upholds
the compatiblity with the original versions for existing architectures
like x86, the legacy syscalls are absent for the recently added AARCH64
architecture. A good overview of the system calls accross the prominent
architectures can be found at

https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md

This patch updates Genode's syscall bindings to avoid legacy versions,
thereby easing the support for AARCH64. The used "modern" versions
were introduced back in Linux version 2 days. So we are fine to rely
on them.

The patch slightly changes the signature for lx_stat because this system
call is merely used to check for the existance of a file and its size.
The new name 'lx_stat_size' draws a closer connection to its use case.
That said, the stat syscall has not been updated to the modern statx
since statx is still a fairly recent addition.

Issue #4136
This commit is contained in:
Norman Feske 2021-05-04 12:18:48 +02:00
parent d477062c56
commit fdb1a4dd88
7 changed files with 26 additions and 19 deletions

View File

@ -32,7 +32,7 @@
inline int lx_mkdir(char const *pathname, mode_t mode)
{
return lx_syscall(SYS_mkdir, pathname, mode);
return lx_syscall(SYS_mkdirat, AT_FDCWD, pathname, mode);
}
@ -44,7 +44,7 @@ inline int lx_ftruncate(int fd, unsigned long length)
inline int lx_unlink(const char *fname)
{
return lx_syscall(SYS_unlink, fname);
return lx_syscall(SYS_unlinkat, AT_FDCWD, fname, 0);
}
@ -52,19 +52,24 @@ inline int lx_unlink(const char *fname)
** Functions used by core's rom-session support code **
*******************************************************/
inline int lx_open(const char *pathname, int flags, mode_t mode = 0)
inline int lx_open(char const *pathname, int flags, mode_t mode = 0)
{
return lx_syscall(SYS_open, pathname, flags, mode);
return lx_syscall(SYS_openat, AT_FDCWD, pathname, flags, mode);
}
inline int lx_stat(const char *path, struct stat64 *buf)
inline int lx_stat_size(char const *path, Genode::uint64_t &out_size)
{
#ifdef _LP64
return lx_syscall(SYS_stat, path, buf);
struct stat buf { };
int result = lx_syscall(SYS_stat, path, &buf);
out_size = buf.st_size;
#else
return lx_syscall(SYS_stat64, path, buf);
struct stat64 buf { };
int result = lx_syscall(SYS_stat64, path, &buf);
out_size = buf.st_size;
#endif
return result;
}
@ -253,7 +258,7 @@ inline int lx_connect(int sockfd, const struct sockaddr *serv_addr,
inline int lx_pipe(int pipefd[2])
{
return lx_syscall(SYS_pipe, pipefd);
return lx_syscall(SYS_pipe2, pipefd, 0);
}

View File

@ -54,10 +54,11 @@ Linux_dataspace::Filename Dataspace_component::_file_name(const char *args)
size_t Dataspace_component::_file_size()
{
struct stat64 s;
if (lx_stat(_fname.buf, &s) < 0) throw Service_denied();
uint64_t size = 0;
if (lx_stat_size(_fname.buf, size) < 0)
throw Service_denied();
return align_addr(s.st_size, 12);
return align_addr(size, 12);
}

View File

@ -53,10 +53,11 @@ Linux_dataspace::Filename Dataspace_component::_file_name(const char *args)
Genode::size_t Dataspace_component::_file_size()
{
struct stat64 s;
if (lx_stat(_fname.buf, &s) < 0) throw Service_denied();
uint64_t size = 0;
if (lx_stat_size(_fname.buf, &size) < 0)
throw Service_denied();
return s.st_size;
return size;
}

View File

@ -117,7 +117,7 @@ inline int lx_dup(int fd)
inline int lx_dup2(int fd, int to)
{
return lx_syscall(SYS_dup2, fd, to);
return lx_syscall(SYS_dup3, fd, to, 0);
}
@ -236,7 +236,7 @@ struct Lx_socketpair
inline Lx_epoll_sd lx_epoll_create()
{
int const ret = lx_syscall(SYS_epoll_create, 1);
int const ret = lx_syscall(SYS_epoll_create1, 0);
if (ret < 0) {
/*
* No recovery possible, just leave a diagnostic message and block
@ -258,7 +258,7 @@ inline int lx_epoll_ctl(Lx_epoll_sd epoll, int op, Lx_sd fd, epoll_event *event)
inline int lx_epoll_wait(Lx_epoll_sd epoll, struct epoll_event *events,
int maxevents, int timeout)
{
return lx_syscall(SYS_epoll_wait, epoll.value, events, maxevents, timeout);
return lx_syscall(SYS_epoll_pwait, epoll.value, events, maxevents, timeout, 0);
}

View File

@ -90,9 +90,9 @@ class Filter
_add_allow_rule(SCMP_SYS(recvmsg));
_add_allow_rule(SCMP_SYS(write));
_add_allow_rule(SCMP_SYS(poll));
_add_allow_rule(SCMP_SYS(epoll_create));
_add_allow_rule(SCMP_SYS(epoll_create1));
_add_allow_rule(SCMP_SYS(epoll_ctl));
_add_allow_rule(SCMP_SYS(epoll_wait));
_add_allow_rule(SCMP_SYS(epoll_pwait));
_add_allow_rule(SCMP_SYS(close));
_add_allow_rule(SCMP_SYS(munmap));
_add_allow_rule(SCMP_SYS(dup));