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 <[email protected]>
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Augustin Cavalier
2023-08-29 19:42:27 +00:00
committed by waddlesplash
parent d57510c0ff
commit 6bde05aebd
5 changed files with 90 additions and 0 deletions
+2
View File
@@ -28,6 +28,8 @@ char *getusershell(void);
int issetugid(void); int issetugid(void);
void setusershell(void); void setusershell(void);
int getentropy(void *buf, size_t buflen);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
+22
View File
@@ -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 <stddef.h>
#define RANDOM_SYSCALLS "random"
#define RANDOM_GET_ENTROPY 1
struct random_get_entropy_args {
void* buffer;
size_t length;
};
#endif /* _KERNEL_RANDOM_DEFS_H */
@@ -13,7 +13,10 @@
#include <device_manager.h> #include <device_manager.h>
#include <Drivers.h> #include <Drivers.h>
#include <generic_syscall.h>
#include <kernel.h>
#include <malloc.h> #include <malloc.h>
#include <random_defs.h>
#include <string.h> #include <string.h>
#include <util/AutoLock.h> #include <util/AutoLock.h>
@@ -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 static status_t
random_close(void *cookie) random_close(void *cookie)
{ {
@@ -197,6 +227,8 @@ random_init_driver(device_node *node, void **cookie)
info->node = node; info->node = node;
register_generic_syscall(RANDOM_SYSCALLS, random_generic_syscall, 1, 0);
*cookie = info; *cookie = info;
return B_OK; return B_OK;
} }
@@ -207,6 +239,8 @@ random_uninit_driver(void *_cookie)
{ {
CALLED(); CALLED();
unregister_generic_syscall(RANDOM_SYSCALLS, 1);
RANDOM_UNINIT(); RANDOM_UNINIT();
mutex_destroy(&sRandomLock); mutex_destroy(&sRandomLock);
+1
View File
@@ -17,6 +17,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
explicit_bzero.c explicit_bzero.c
fgetln.c fgetln.c
fts.c fts.c
getentropy.c
getpass.c getpass.c
issetugid.c issetugid.c
kqueue.cpp kqueue.cpp
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright 2023, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <unistd.h>
#include <libroot/errno_private.h>
#include <random_defs.h>
#include <syscalls.h>
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;
}