[LibOS] Implement getrandom syscall

This commit is contained in:
Michał Kowalczyk
2020-09-25 09:29:52 +02:00
parent 6b6bdb28b2
commit 0c951dbe9d
6 changed files with 61 additions and 15 deletions
+5
View File
@@ -537,5 +537,10 @@ ssize_t shim_do_sendmmsg(int sockfd, struct mmsghdr* msg, unsigned int vlen, int
int shim_do_eventfd2(unsigned int count, int flags);
int shim_do_eventfd(unsigned int count);
int shim_do_getcpu(unsigned* cpu, unsigned* node, struct getcpu_cache* unused);
long shim_do_getrandom(char* buf, size_t count, unsigned int flags);
#define GRND_NONBLOCK 0x0001
#define GRND_RANDOM 0x0002
#define GRND_INSECURE 0x0004
#endif /* _SHIM_TABLE_H_ */
+1
View File
@@ -93,6 +93,7 @@ objs = \
sys/shim_futex.o \
sys/shim_getcwd.o \
sys/shim_getpid.o \
sys/shim_getrandom.o \
sys/shim_getrlimit.o \
sys/shim_ioctl.o \
sys/shim_mmap.o \
+18 -1
View File
@@ -52,6 +52,7 @@ static void parse_seek(va_list*);
static void parse_at_fdcwd(va_list*);
static void parse_wait_options(va_list*);
static void parse_waitid_which(va_list*);
static void parse_getrandom_flags(va_list*);
struct parser_table {
int slow;
@@ -386,7 +387,7 @@ struct parser_table {
[__NR_sched_getattr] = {.slow = 0, .parser = {NULL}},
[__NR_renameat2] = {.slow = 0, .parser = {NULL}},
[__NR_seccomp] = {.slow = 0, .parser = {NULL}},
[__NR_getrandom] = {.slow = 0, .parser = {NULL}},
[__NR_getrandom] = {.slow = 0, .parser = {NULL, NULL, parse_getrandom_flags}},
[__NR_memfd_create] = {.slow = 0, .parser = {NULL}},
[__NR_kexec_file_load] = {.slow = 0, .parser = {NULL}},
[__NR_bpf] = {.slow = 0, .parser = {NULL}},
@@ -1395,3 +1396,19 @@ static void parse_waitid_which(va_list* ap) {
break;
}
}
static void parse_getrandom_flags(va_list* ap) {
unsigned int flags = va_arg(*ap, unsigned int);
#define FLG(n) { #n, n }
const struct flag_table all_flags[] = {
FLG(GRND_NONBLOCK),
FLG(GRND_RANDOM),
FLG(GRND_INSECURE),
};
#undef FLG
flags = parse_flags(flags, all_flags, ARRAY_SIZE(all_flags));
if (flags)
PRINTF("|0x%x", flags);
}
+2 -1
View File
@@ -1060,7 +1060,8 @@ SHIM_SYSCALL_RETURN_ENOSYS(renameat2, 5, long, int, olddfd, const char*, oldname
SHIM_SYSCALL_RETURN_ENOSYS(seccomp, 3, long, unsigned int, op, unsigned int, flags, void*, uargs)
SHIM_SYSCALL_RETURN_ENOSYS(getrandom, 3, long, char*, buf, size_t, count, unsigned int, flags)
DEFINE_SHIM_SYSCALL(getrandom, 3, shim_do_getrandom, long, char*, buf, size_t, count, unsigned int,
flags)
SHIM_SYSCALL_RETURN_ENOSYS(memfd_create, 2, long, const char*, uname, unsigned int, flags)
+34
View File
@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/* Copyright (C) 2020 Intel Corporation
* Michał Kowalczyk <mkow@invisiblethingslab.com>
*/
#include <limits.h>
#include <stdint.h>
#include "shim_internal.h"
#include "shim_table.h"
long shim_do_getrandom(char* buf, size_t count, unsigned int flags) {
if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE))
return -EINVAL;
if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
return -EINVAL;
/* Weird, but that's what kernel does */
if (count > INT_MAX)
count = INT_MAX;
if (test_user_memory(buf, count, /*write=*/true))
return -EFAULT;
/* In theory, DkRandomBitsRead may block on some PALs (which conflicts with GRND_NONBLOCK flag),
* but this shouldn't be possible in practice, so we don't care.
*/
int ret = DkRandomBitsRead(buf, count);
if (ret < 0)
return -EINVAL;
return count;
}
+1 -13
View File
@@ -180,7 +180,7 @@ must-pass =
3
[clock_nanosleep02]
must-pass =
skip = yes
[clock_nanosleep2_01]
skip = yes
@@ -871,18 +871,6 @@ skip = yes
[getpriority02]
skip = yes
[getrandom01]
skip = yes
[getrandom02]
skip = yes
[getrandom03]
skip = yes
[getrandom04]
skip = yes
[getresgid01]
skip = yes