Skip to content

Commit 777cf2c

Browse files
authored
Port random numbers to use wasip2 methods (#612)
1 parent b530caf commit 777cf2c

File tree

6 files changed

+84
-2
lines changed

6 files changed

+84
-2
lines changed

expected/wasm32-wasip2/defined-symbols.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ __wasilibc_nocwd_utimensat
381381
__wasilibc_open_nomode
382382
__wasilibc_populate_preopens
383383
__wasilibc_pthread_self
384+
__wasilibc_random
384385
__wasilibc_register_preopened_fd
385386
__wasilibc_rename_newat
386387
__wasilibc_rename_oldat

libc-bottom-half/headers/public/wasi/libc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <__typedef_off_t.h>
55
#include <__struct_timespec.h>
6+
#include <unistd.h>
67

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

71+
/// Fill a buffer with random bytes
72+
int __wasilibc_random(void* buffer, size_t len)
73+
__attribute__((__warn_unused_result__));
74+
7075
#ifdef __cplusplus
7176
}
7277
#endif
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <errno.h>
2+
#include <unistd.h>
3+
#ifdef __wasilibc_use_wasip2
4+
#include <wasi/wasip2.h>
5+
#include <sysexits.h>
6+
7+
int __wasilibc_random(void *buffer, size_t len) {
8+
9+
// Set up a WASI byte list to receive the results
10+
wasip2_list_u8_t wasi_list;
11+
12+
// Get random bytes
13+
random_get_random_bytes(len, &wasi_list);
14+
15+
// The spec for get-random-bytes specifies that wasi_list.len
16+
// will be equal to len.
17+
if (wasi_list.len != len)
18+
_Exit(EX_OSERR);
19+
else {
20+
// Copy the result
21+
memcpy(buffer, wasi_list.ptr, len);
22+
}
23+
24+
// Free the WASI byte list
25+
wasip2_list_u8_free(&wasi_list);
26+
27+
return 0;
28+
}
29+
#endif

libc-bottom-half/sources/getentropy.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
#include <errno.h>
22
#include <unistd.h>
3+
#ifdef __wasilibc_use_wasip2
4+
#include <wasi/libc.h>
5+
#else
36
#include <wasi/api.h>
7+
#endif
48

59
int __getentropy(void *buffer, size_t len) {
610
if (len > 256) {
711
errno = EIO;
812
return -1;
913
}
1014

15+
#ifdef __wasilibc_use_wasip2
16+
int r = __wasilibc_random(buffer, len);
17+
#else
1118
int r = __wasi_random_get(buffer, len);
12-
19+
#endif
1320
if (r != 0) {
1421
errno = r;
1522
return -1;
1623
}
17-
1824
return 0;
1925
}
2026
weak_alias(__getentropy, getentropy);

libc-top-half/musl/src/env/__stack_chk_fail.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,22 @@ hidden void __stack_chk_fail_local(void);
3838
weak_alias(__stack_chk_fail, __stack_chk_fail_local);
3939

4040
#ifndef __wasilibc_unmodified_upstream
41+
#ifdef __wasilibc_use_wasip2
42+
# include <wasi/libc.h>
43+
#else
4144
# include <wasi/api.h>
45+
#endif
4246

4347
__attribute__((constructor(60)))
4448
static void __wasilibc_init_ssp(void) {
4549
uintptr_t entropy;
50+
#ifdef __wasilibc_use_wasip2
51+
int len = sizeof(uintptr_t);
52+
53+
int r = __wasilibc_random(&entropy, len);
54+
#else
4655
int r = __wasi_random_get((uint8_t *)&entropy, sizeof(uintptr_t));
56+
#endif
4757
__init_ssp(r ? NULL : &entropy);
4858
}
4959
#endif

test/src/misc/getentropy.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//! add-flags.py(CFLAGS): -I.
2+
//! add-flags.py(ARGS): foo bar
3+
#include <limits.h>
4+
#include <stdio.h>
5+
#include "test.h"
6+
7+
#define TEST(c, ...) \
8+
( (c) || (t_error(#c " failed: " __VA_ARGS__),0) )
9+
10+
int main()
11+
{
12+
size_t len = 256;
13+
uint8_t buffer[len];
14+
15+
TEST(getentropy(&buffer, len) == 0, "getentropy() should return 0\n");
16+
int all_zeroes = 1;
17+
18+
for (size_t i = 0; i < len; i++) {
19+
if (buffer[i] != 0) {
20+
all_zeroes = 0;
21+
break;
22+
}
23+
}
24+
25+
TEST(all_zeroes == 0, "getentropy() returned 256 zeroes\n");
26+
27+
// More than 256 bytes is an error
28+
TEST(getentropy(&buffer, 257)==-1, "requesting > 256 bytes should be an error\n");
29+
30+
return t_status;
31+
}

0 commit comments

Comments
 (0)