From 6bde05aebd17e946ea8af7ef4e55cb609aa4c68e Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 29 Aug 2023 14:18:05 -0400 Subject: [PATCH] libs/bsd: Implement getentropy(2). With generic_syscall to avoid using a FD. Change-Id: Id1702118bb673f06a861e4f0ad3401ce3d45cbd0 Reviewed-on: https://review.haiku-os.org/c/haiku/+/31 Reviewed-by: waddlesplash Tested-by: Commit checker robot Reviewed-by: Adrien Destugues --- headers/compatibility/bsd/unistd.h | 2 ++ headers/private/system/random_defs.h | 22 ++++++++++++ .../kernel/bus_managers/random/driver.cpp | 34 +++++++++++++++++++ src/libs/bsd/Jamfile | 1 + src/libs/bsd/getentropy.c | 31 +++++++++++++++++ 5 files changed, 90 insertions(+) create mode 100644 headers/private/system/random_defs.h create mode 100644 src/libs/bsd/getentropy.c diff --git a/headers/compatibility/bsd/unistd.h b/headers/compatibility/bsd/unistd.h index 5bc3045954..e43fe76c2f 100644 --- a/headers/compatibility/bsd/unistd.h +++ b/headers/compatibility/bsd/unistd.h @@ -28,6 +28,8 @@ char *getusershell(void); int issetugid(void); void setusershell(void); +int getentropy(void *buf, size_t buflen); + #ifdef __cplusplus } #endif diff --git a/headers/private/system/random_defs.h b/headers/private/system/random_defs.h new file mode 100644 index 0000000000..539e985fff --- /dev/null +++ b/headers/private/system/random_defs.h @@ -0,0 +1,22 @@ +/* + * Copyright 2023, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_RANDOM_DEFS_H +#define _KERNEL_RANDOM_DEFS_H + + +#include + + +#define RANDOM_SYSCALLS "random" +#define RANDOM_GET_ENTROPY 1 + + +struct random_get_entropy_args { + void* buffer; + size_t length; +}; + + +#endif /* _KERNEL_RANDOM_DEFS_H */ diff --git a/src/add-ons/kernel/bus_managers/random/driver.cpp b/src/add-ons/kernel/bus_managers/random/driver.cpp index d85dc012a1..752c9c48e9 100644 --- a/src/add-ons/kernel/bus_managers/random/driver.cpp +++ b/src/add-ons/kernel/bus_managers/random/driver.cpp @@ -13,7 +13,10 @@ #include #include +#include +#include #include +#include #include #include @@ -103,6 +106,33 @@ random_control(void *cookie, uint32 op, void *arg, size_t length) } +static status_t +random_generic_syscall(const char* subsystem, uint32 function, void* buffer, + size_t bufferSize) +{ + switch (function) { + case RANDOM_GET_ENTROPY: + { + random_get_entropy_args args; + if (bufferSize != sizeof(args) || !IS_USER_ADDRESS(buffer)) + return B_BAD_VALUE; + + if (user_memcpy(&args, buffer, sizeof(args)) != B_OK) + return B_BAD_ADDRESS; + if (!IS_USER_ADDRESS(args.buffer)) + return B_BAD_ADDRESS; + + status_t result = random_read(NULL, 0, args.buffer, &args.length); + if (result < 0) + return result; + + return user_memcpy(buffer, &args, sizeof(args)); + } + } + return B_BAD_HANDLER; +} + + static status_t random_close(void *cookie) { @@ -197,6 +227,8 @@ random_init_driver(device_node *node, void **cookie) info->node = node; + register_generic_syscall(RANDOM_SYSCALLS, random_generic_syscall, 1, 0); + *cookie = info; return B_OK; } @@ -207,6 +239,8 @@ random_uninit_driver(void *_cookie) { CALLED(); + unregister_generic_syscall(RANDOM_SYSCALLS, 1); + RANDOM_UNINIT(); mutex_destroy(&sRandomLock); diff --git a/src/libs/bsd/Jamfile b/src/libs/bsd/Jamfile index aa5ea6df69..4994732fe2 100644 --- a/src/libs/bsd/Jamfile +++ b/src/libs/bsd/Jamfile @@ -17,6 +17,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { explicit_bzero.c fgetln.c fts.c + getentropy.c getpass.c issetugid.c kqueue.cpp diff --git a/src/libs/bsd/getentropy.c b/src/libs/bsd/getentropy.c new file mode 100644 index 0000000000..74d1e1936b --- /dev/null +++ b/src/libs/bsd/getentropy.c @@ -0,0 +1,31 @@ +/* + * Copyright 2023, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include + +#include +#include +#include + + +int +getentropy(void *buf, size_t buflen) +{ + status_t status; + struct random_get_entropy_args args; + args.buffer = buf; + args.length = buflen; + + status = _kern_generic_syscall(RANDOM_SYSCALLS, RANDOM_GET_ENTROPY, + &args, sizeof(args)); + if (args.length < buflen) + status = EIO; + + if (status < 0) { + __set_errno(status); + return -1; + } + return 0; +}