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:
committed by
waddlesplash
parent
d57510c0ff
commit
6bde05aebd
@@ -28,6 +28,8 @@ char *getusershell(void);
|
||||
int issetugid(void);
|
||||
void setusershell(void);
|
||||
|
||||
int getentropy(void *buf, size_t buflen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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 <Drivers.h>
|
||||
#include <generic_syscall.h>
|
||||
#include <kernel.h>
|
||||
#include <malloc.h>
|
||||
#include <random_defs.h>
|
||||
#include <string.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
|
||||
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);
|
||||
|
||||
@@ -17,6 +17,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
explicit_bzero.c
|
||||
fgetln.c
|
||||
fts.c
|
||||
getentropy.c
|
||||
getpass.c
|
||||
issetugid.c
|
||||
kqueue.cpp
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user