mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 02:12:09 -05:00
Kernel: Add a Linux-style getrandom syscall
The way it gets the entropy and blasts it to the buffer is pretty ugly IMHO, but it does work for now. (It should be replaced, by not truncating a u32.) It implements an (unused for now) flags argument, like Linux but instead of OpenBSD's. This is in case we want to distinguish between entropy sources or any other reason and have to implement a new syscall later. Of course, learn from Linux's struggles with entropy sourcing too.
This commit is contained in:
parent
0e61d84749
commit
7e4e092653
4 changed files with 26 additions and 1 deletions
|
@ -8,6 +8,7 @@
|
|||
#include <Kernel/Arch/i386/CPU.h>
|
||||
#include <Kernel/Arch/i386/PIT.h>
|
||||
#include <Kernel/Devices/NullDevice.h>
|
||||
#include <Kernel/Devices/RandomDevice.h>
|
||||
#include <Kernel/FileSystem/Custody.h>
|
||||
#include <Kernel/FileSystem/DevPtsFS.h>
|
||||
#include <Kernel/FileSystem/Ext2FileSystem.h>
|
||||
|
@ -3076,3 +3077,23 @@ int Process::sys$get_process_name(char* buffer, int buffer_size)
|
|||
strncpy(buffer, m_name.characters(), buffer_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We don't use the flag yet, but we could use it for distinguishing
|
||||
// random source like Linux, unlike the OpenBSD equivalent. However, if we
|
||||
// do, we should be able of the caveats that Linux has dealt with.
|
||||
int Process::sys$getrandom(void* buffer, size_t buffer_size, unsigned int flags __attribute__((unused)))
|
||||
{
|
||||
if (buffer_size <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!validate_write(buffer, buffer_size))
|
||||
return -EFAULT;
|
||||
// XXX: We probably lose a lot of entropy here, out of an already marginal
|
||||
// PRNG. A better implementation would not throw away bits for the sake of
|
||||
// array indexing, and use a better PRNG in the first place.
|
||||
uint8_t* bytes = (uint8_t*)buffer;
|
||||
for (size_t i = 0; i < buffer_size; i++)
|
||||
bytes[i] = (uint8_t)(RandomDevice::random_value() % 255);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -225,6 +225,7 @@ public:
|
|||
int sys$reboot();
|
||||
int sys$set_process_icon(int icon_id);
|
||||
int sys$realpath(const char* pathname, char*, size_t);
|
||||
ssize_t sys$getrandom(void*, size_t, unsigned int);
|
||||
|
||||
static void initialize();
|
||||
|
||||
|
|
|
@ -313,6 +313,8 @@ static u32 handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3
|
|||
return current->process().sys$get_process_name((char*)arg1, (int)arg2);
|
||||
case Syscall::SC_realpath:
|
||||
return current->process().sys$realpath((const char*)arg1, (char*)arg2, (size_t)arg3);
|
||||
case Syscall::SC_getrandom:
|
||||
return current->process().sys$getrandom((void*)arg1, (size_t)arg2, (unsigned int)arg3);
|
||||
default:
|
||||
kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3);
|
||||
return -ENOSYS;
|
||||
|
|
|
@ -130,7 +130,8 @@ struct timeval;
|
|||
__ENUMERATE_SYSCALL(mprotect) \
|
||||
__ENUMERATE_SYSCALL(realpath) \
|
||||
__ENUMERATE_SYSCALL(get_process_name) \
|
||||
__ENUMERATE_SYSCALL(fchdir)
|
||||
__ENUMERATE_SYSCALL(fchdir) \
|
||||
__ENUMERATE_SYSCALL(getrandom)
|
||||
|
||||
namespace Syscall {
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue