diff --git a/LibOS/shim/include/shim_table.h b/LibOS/shim/include/shim_table.h index 25e7029b..3d0271d1 100644 --- a/LibOS/shim/include/shim_table.h +++ b/LibOS/shim/include/shim_table.h @@ -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_ */ diff --git a/LibOS/shim/src/Makefile b/LibOS/shim/src/Makefile index b7568d24..ae0c39d7 100644 --- a/LibOS/shim/src/Makefile +++ b/LibOS/shim/src/Makefile @@ -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 \ diff --git a/LibOS/shim/src/shim_parser.c b/LibOS/shim/src/shim_parser.c index 832e6390..94d6a099 100644 --- a/LibOS/shim/src/shim_parser.c +++ b/LibOS/shim/src/shim_parser.c @@ -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); +} diff --git a/LibOS/shim/src/shim_syscalls.c b/LibOS/shim/src/shim_syscalls.c index d68e9f3b..28f19c8e 100644 --- a/LibOS/shim/src/shim_syscalls.c +++ b/LibOS/shim/src/shim_syscalls.c @@ -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) diff --git a/LibOS/shim/src/sys/shim_getrandom.c b/LibOS/shim/src/sys/shim_getrandom.c new file mode 100644 index 00000000..057259af --- /dev/null +++ b/LibOS/shim/src/sys/shim_getrandom.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* Copyright (C) 2020 Intel Corporation + * MichaƂ Kowalczyk + */ + +#include +#include + +#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; +} diff --git a/LibOS/shim/test/ltp/ltp.cfg b/LibOS/shim/test/ltp/ltp.cfg index b7113a54..ffdc847f 100644 --- a/LibOS/shim/test/ltp/ltp.cfg +++ b/LibOS/shim/test/ltp/ltp.cfg @@ -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