Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions expected/wasm32-wasip2/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ __wasilibc_nocwd_utimensat
__wasilibc_open_nomode
__wasilibc_populate_preopens
__wasilibc_pthread_self
__wasilibc_random
__wasilibc_register_preopened_fd
__wasilibc_rename_newat
__wasilibc_rename_oldat
Expand Down
5 changes: 5 additions & 0 deletions libc-bottom-half/headers/public/wasi/libc.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <__typedef_off_t.h>
#include <__struct_timespec.h>
#include <unistd.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -67,6 +68,10 @@ int __wasilibc_rename_newat(const char *oldpath, int newdirfd, const char *newpa
/// Enable busywait in futex on current thread.
void __wasilibc_enable_futex_busywait_on_current_thread(void);

/// Fill a buffer with random bytes
int __wasilibc_random(void* buffer, size_t len)
__attribute__((__warn_unused_result__));

#ifdef __cplusplus
}
#endif
Expand Down
29 changes: 29 additions & 0 deletions libc-bottom-half/sources/__wasilibc_random.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <errno.h>
#include <unistd.h>
#ifdef __wasilibc_use_wasip2
#include <wasi/wasip2.h>
#include <sysexits.h>

int __wasilibc_random(void *buffer, size_t len) {

// Set up a WASI byte list to receive the results
wasip2_list_u8_t wasi_list;

// Get random bytes
random_get_random_bytes(len, &wasi_list);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little hesitant to handle this error by returning, vs exiting with EX_OSERR or something, since the docs of get-random-bytes guarantee that the wasi_list len will be equal to len. WDYT about exiting instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. Changed in cdcd442


// The spec for get-random-bytes specifies that wasi_list.len
// will be equal to len.
if (wasi_list.len != len)
_Exit(EX_OSERR);
else {
// Copy the result
memcpy(buffer, wasi_list.ptr, len);
}

// Free the WASI byte list
wasip2_list_u8_free(&wasi_list);

return 0;
}
#endif
10 changes: 8 additions & 2 deletions libc-bottom-half/sources/getentropy.c
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
#include <errno.h>
#include <unistd.h>
#ifdef __wasilibc_use_wasip2
#include <wasi/libc.h>
#else
#include <wasi/api.h>
#endif

int __getentropy(void *buffer, size_t len) {
if (len > 256) {
errno = EIO;
return -1;
}

#ifdef __wasilibc_use_wasip2
int r = __wasilibc_random(buffer, len);
#else
int r = __wasi_random_get(buffer, len);

#endif
if (r != 0) {
errno = r;
return -1;
}

return 0;
}
weak_alias(__getentropy, getentropy);
10 changes: 10 additions & 0 deletions libc-top-half/musl/src/env/__stack_chk_fail.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,22 @@ hidden void __stack_chk_fail_local(void);
weak_alias(__stack_chk_fail, __stack_chk_fail_local);

#ifndef __wasilibc_unmodified_upstream
#ifdef __wasilibc_use_wasip2
# include <wasi/libc.h>
#else
# include <wasi/api.h>
#endif

__attribute__((constructor(60)))
static void __wasilibc_init_ssp(void) {
uintptr_t entropy;
#ifdef __wasilibc_use_wasip2
int len = sizeof(uintptr_t);

int r = __wasilibc_random(&entropy, len);
#else
int r = __wasi_random_get((uint8_t *)&entropy, sizeof(uintptr_t));
#endif
__init_ssp(r ? NULL : &entropy);
}
#endif
31 changes: 31 additions & 0 deletions test/src/misc/getentropy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//! add-flags.py(CFLAGS): -I.
//! add-flags.py(ARGS): foo bar
#include <limits.h>
#include <stdio.h>
#include "test.h"

#define TEST(c, ...) \
( (c) || (t_error(#c " failed: " __VA_ARGS__),0) )

int main()
{
size_t len = 256;
uint8_t buffer[len];

TEST(getentropy(&buffer, len) == 0, "getentropy() should return 0\n");
int all_zeroes = 1;

for (size_t i = 0; i < len; i++) {
if (buffer[i] != 0) {
all_zeroes = 0;
break;
}
}

TEST(all_zeroes == 0, "getentropy() returned 256 zeroes\n");

// More than 256 bytes is an error
TEST(getentropy(&buffer, 257)==-1, "requesting > 256 bytes should be an error\n");

return t_status;
}
Loading