Skip to content

Commit 09ba91f

Browse files
stupendoussuperpowersrennergadeJustinCapposYaxuan-wdependabot[bot]
authored
Encode cageids to enable address translations: (arg, cageid) tuple independence from calling cages. (#913)
* Encode arg cageid translation flag * make it look not insane * Changes post test runs. * Reorganize docs and add clamping/stacking paragraphs (#711) * reorganize docs, add image, add clamping/stacking paragraphs * add link * Update docs/internal/grates.md Co-authored-by: Justin Cappos <justincappos@gmail.com> * 3i comment updates * more 3i comment updates * index update * grate changes: more on clamping, motivation * resolve grate comments * add examples and more on clamping * Update wasmtime doc * Update wasmtime * update example * update clamping section * add clamping doc * Update docs/internal/clamping.md Co-authored-by: Justin Cappos <justincappos@gmail.com> * Apply suggestion from @JustinCappos Co-authored-by: Justin Cappos <justincappos@gmail.com> * resolve some comments * resolve some comments * fix unclear memory comment --------- Co-authored-by: Justin Cappos <justincappos@gmail.com> Co-authored-by: Alice W <wenyaxuan0925@outlook.com> * Force-link signal_callback export in crt1.c (#916) Programs that never call sigaction() (e.g. kill.c) would not link in libc_sigaction.o, so signal_callback was missing from the wasm exports. The epoch-based signal handler in wasmtime looks up this export at runtime, causing a panic when delivering signals to such programs. Fix: add a __attribute__((used)) reference to signal_callback in crt1.c so it is always exported from every wasm binary. * refactor handler resolution logic to remove usage of operational_cageid in rawposix (#900) * refactor traget cageid usage in 3i and rawposix * Squashed commit of the following: commit 5756372 Author: Nicholas Renner <nr2185@nyu.edu> Date: Tue Mar 10 09:58:37 2026 -0400 Restore wasip linker for rust (#902) * restore wasip linker for rust * Deduplicate wasip1/lind environ linker functions, fix rustfmt Merge add_environ_to_linker and add_wasi_compat_to_linker into a single add_environ_funcs_to_linker that takes a module name parameter. Called twice with "lind" and "wasi_snapshot_preview1" to register identical implementations under both namespaces. Fixes cargo fmt lint failure. commit fee8b37 Author: Nicholas Renner <nr2185@nyu.edu> Date: Mon Mar 9 22:54:30 2026 -0400 Signal EINTR + Asyncify updates (349 update) (#906) * update PR to integrated signal EINTR with lind-boot * Remove spurious set_stack_pointer call in fork child path The set_stack_pointer call was carried over from the old asyncify branch but is not needed in the new architecture. The fork child's stack pointer is correctly managed by the asyncify rewind mechanism. Calling set_stack_pointer before the rewind interfered with the fork process, causing all fork-based tests to deadlock/timeout. * Rewrite eintr_fork_signal test to use spin loop instead of blocking read The original test used alarm(1) + blocking read(pipe), but RawPOSIX's read() calls host libc::read() directly, which blocks in the host kernel. Since SIGALRM is delivered via epoch callback (which requires wasm to be executing), the blocking read can never be interrupted. Rewrite to use a spin loop that allows the epoch to fire and deliver the signal. commit f15676e Author: Alice Wen <40227173+Yaxuan-w@users.noreply.github.com> Date: Mon Mar 9 21:28:46 2026 -0400 Implement structured exit status handling and correct POSIX wait status encoding (#910) * Fix exit code handling to include signal termination * Revert fs_call * Remove redundant bit check * Not using sleep to sync in test commit f135811 Author: Nicholas Renner <nr2185@nyu.edu> Date: Mon Mar 9 18:51:24 2026 -0400 determinize resolve test (#912) commit a8798b6 Author: Alice Wen <40227173+Yaxuan-w@users.noreply.github.com> Date: Mon Mar 9 17:58:01 2026 -0400 Fix exit code mismatch between wasmtime and lind-boot exit (#856) * Fix exit code mismatch * Update skipped list * Skip test case * Handle system err return * Fix merge conflicts commit 750ba9a Author: Qianxi Chen <53324229+qianxichen233@users.noreply.github.com> Date: Mon Mar 9 13:58:23 2026 -0400 unify execute_wasmtime and execute_with_lind (#903) commit e5eb83c Author: Qianxi Chen <53324229+qianxichen233@users.noreply.github.com> Date: Mon Mar 9 13:57:55 2026 -0400 update wasm-opt for dylink support (#905) commit 086224d Author: Huong Hoang <68453624+celinehoang177@users.noreply.github.com> Date: Mon Mar 9 12:10:52 2026 -0400 Replace hardcoded numbers in codebase with named constants (Rust + C) (#855) * replace hardcoded numbers in codebase with named constants * replace padding 0s with NOTUSED/UNUSED_ID/UNUSED_ARG commit 89ef9bd Author: Nicholas Renner <nr2185@nyu.edu> Date: Mon Mar 9 11:18:37 2026 -0400 Fix remote DNS (#898) * dns remote resolv * add fionread * lint * Refine 3i get_handler and solve exec/exit/clone issue * Fix exec * update gitignore (#920) * deps(gha)(deps): bump docker/metadata-action in /.github/workflows (#925) * deps(gha)(deps): bump docker/build-push-action in /.github/workflows (#926) * deps(gha)(deps): bump docker/setup-buildx-action in /.github/workflows (#928) * deps(gha)(deps): bump zizmorcore/zizmor-action from 0.5.0 to 0.5.2 in /.github/workflows (#927) * deps(gha)(deps): bump zizmorcore/zizmor-action in /.github/workflows Bumps [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) from 0.5.0 to 0.5.2. - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](zizmorcore/zizmor-action@0dce257...71321a2) --- updated-dependencies: - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * add dedicated environment for zizmor compatibility --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Natasha Hemmings <discount.yoyos@gmail.com> * Fix getaddrinfo() with PF_UNSPEC (#935) * Fix getaddrinfo PF_UNSPEC: stub out sendmmsg for Lind-WASM getaddrinfo() with PF_UNSPEC failed with "Temporary failure in name resolution" because glibc's DNS resolver (res_send.c) tried to send parallel A+AAAA queries using sendmmsg(), which is not implemented in Lind. With __ASSUME_SENDMMSG defined, the fallback to individual send() calls was compiled out, so the sendmmsg failure was fatal. Fix: - Stub __sendmmsg to return ENOSYS immediately (no syscall dispatch) - Undefine __ASSUME_SENDMMSG in kernel-features.h so res_send.c compiles in the fallback path that uses individual __send() calls When sendmmsg returns ENOSYS, res_send.c sets have_sendmmsg=-1 and falls through to try_send, which sends each DNS query individually. Subsequent calls skip sendmmsg entirely. Closes #934 * Add getaddrinfo PF_UNSPEC test * make test failure return error code in make file to stop process (#936) * make test failure return error code in make file to stop process * Add deliberately failing ci test file * intentional failing tests should now force E2E_STATUS=fail * Skip ci-test file to prevent actual failures * move test location to ci folder * update test harness to include the ci folder * change skipped test location for ci test * Fix random_get: route through make_syscall instead of /dev/urandom (#940) lind-boot chroots to lindfs where /dev/urandom doesn't exist, causing a panic in random_get. Route through 3i make_syscall to the existing getrandom_syscall handler (syscall 318) in rawposix. Fixes #919 * Fix test output * WIP : Glibc fixes to fix build errors and undefined symbol errors (#793) * Added placeholder for libdl.a * Added unwind_def object file for libc.a * Updated s_frexpl.c with latest glibc code to fix the build error * Disable compiler flags -mno-sse, -mno-mmx, -mfpmath-387 that are not supported by wasm and caused build errors * Disable ELF symbol versioning and hidden visibility in glibc shared builds which caused undefined symbol error for pow etc * Removed flags that is not supported in wasm * resolve comments. * Revert "Merge branch 'main' of github.com:Lind-Project/lind-wasm into encode-argid" This reverts commit a758efd, reversing changes made to 061322b. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Nicholas Renner <nr2185@nyu.edu> Co-authored-by: Justin Cappos <justincappos@gmail.com> Co-authored-by: Alice W <wenyaxuan0925@outlook.com> Co-authored-by: Alice Wen <40227173+Yaxuan-w@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Natasha Hemmings <discount.yoyos@gmail.com> Co-authored-by: Vidya Lakshmi Rajagopalan <vidyalakshmir@users.noreply.github.com>
1 parent d04cf8c commit 09ba91f

File tree

4 files changed

+192
-12
lines changed

4 files changed

+192
-12
lines changed

src/glibc/lind_syscall/addr_translation.h

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
#include <stddef.h>
66
#include <errno.h>
77

8+
// With the new semantics, a cageid with its MSB set indicates that the
9+
// associated argument should be translated. These helpers manage that flag.
10+
//
11+
// Flag indicating the argument requires translation (MSB set).
12+
#define LIND_ARG_TRANSLATE_FLAG (1ULL << 63)
13+
14+
// Mask to extract the actual cageid (clear the translation flag).
15+
#define LIND_ARG_CAGEID_MASK (~LIND_ARG_TRANSLATE_FLAG)
16+
817
#ifdef __cplusplus
918
extern "C"
1019
{
@@ -45,7 +54,13 @@ extern "C"
4554
static inline uint64_t
4655
__lind_translate_uaddr_to_host (const uint64_t uaddr, const uint64_t cageid)
4756
{
48-
if (cageid == __lind_cageid)
57+
// Extract actual cageid (without the translation flag)
58+
uint64_t __cageid = cageid & LIND_ARG_CAGEID_MASK;
59+
60+
// Translate only if:
61+
// 1. The argument originates from the current cage, and
62+
// 2. MSB of cageid is set.
63+
if (__cageid == __lind_cageid && ((cageid & LIND_ARG_TRANSLATE_FLAG) != 0))
4964
return __lind_base + uaddr;
5065

5166
return uaddr;
@@ -55,10 +70,24 @@ extern "C"
5570
#define TRANSLATE_GUEST_POINTER_TO_HOST(p) \
5671
__lind_translate_ptr_to_host ((const void *) (p))
5772

58-
// Converts (uaddr, cageid) pair to host address.
59-
// Useful when address space (cage vs host) is ambigious.
73+
// Convert a (uaddr, cageid) pair to (host_addr, cageid).
74+
//
75+
// Used by copy_data_between_cages where arguments are already addresses. This macro
76+
// sets the translation flag before invoking the helper.
77+
//
78+
// Input: (uaddr, cageid)
79+
// Output: (host_addr, cageid)
6080
#define TRANSLATE_UADDR_TO_HOST(uaddr, cageid) \
61-
__lind_translate_uaddr_to_host ((uaddr), (cageid))
81+
__lind_translate_uaddr_to_host ((uaddr), ((cageid) | LIND_ARG_TRANSLATE_FLAG)), (cageid)
82+
83+
// Used by make_threei_call to translate arguments if required.
84+
//
85+
// Translation occurs only when the MSB of cageid is set.
86+
//
87+
// Input: (uaddr, cageid)
88+
// Output: (host_addr, actual_cageid)
89+
#define TRANSLATE_ARG_TO_HOST(uaddr, cageid) \
90+
__lind_translate_uaddr_to_host ((uaddr), (cageid)), ((cageid) & LIND_ARG_CAGEID_MASK)
6291

6392
/* Translate an array of guest iovec structures to host layout.
6493
Each iov_base is a wasm32 guest pointer; we split the translated

src/glibc/lind_syscall/lind_syscall.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,13 @@ int make_threei_call (unsigned int callnumber,
8181
int ret = __lind_make_syscall_trampoline(callnumber,
8282
callname,
8383
self_cageid, target_cageid,
84-
arg1, arg1cageid,
85-
arg2, arg2cageid,
86-
arg3, arg3cageid,
87-
arg4, arg4cageid,
88-
arg5, arg5cageid,
89-
arg6, arg6cageid);
84+
TRANSLATE_ARG_TO_HOST(arg1, arg1cageid),
85+
TRANSLATE_ARG_TO_HOST(arg2, arg2cageid),
86+
TRANSLATE_ARG_TO_HOST(arg3, arg3cageid),
87+
TRANSLATE_ARG_TO_HOST(arg4, arg4cageid),
88+
TRANSLATE_ARG_TO_HOST(arg5, arg5cageid),
89+
TRANSLATE_ARG_TO_HOST(arg6, arg6cageid));
90+
9091
// if translate_errno is not enabled, we do not do any further process to errno handling and directly return the result
9192
if(translate_errno == TRANSLATE_ERRNO_OFF) return ret;
9293
// handle the errno
@@ -155,8 +156,8 @@ int copy_data_between_cages(uint64_t thiscage, uint64_t targetcage, uint64_t src
155156
NOTUSED, // callname is not used in the trampoline
156157
thiscage, // self_cageid
157158
thiscage, // target_cageid. Self_cageid and target_cageid are the same to adapt with regular make_syscall lookup logic in 3i
158-
TRANSLATE_UADDR_TO_HOST(srcaddr, srccage), srccage,
159-
TRANSLATE_UADDR_TO_HOST(destaddr, destcage), destcage,
159+
TRANSLATE_UADDR_TO_HOST(srcaddr, srccage),
160+
TRANSLATE_UADDR_TO_HOST(destaddr, destcage),
160161
len, NOTUSED,
161162
copytype, NOTUSED,
162163
NOTUSED, NOTUSED, NOTUSED, NOTUSED,

tests/grate-tests/diff-cage-args.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <stdio.h>
2+
#include <unistd.h>
3+
#include <fcntl.h>
4+
5+
int main() {
6+
int fd = open("redirected.txt", O_RDONLY, 0);
7+
printf("Hello world. FD=%d\n", fd);
8+
9+
char buf[11];
10+
int ret = read(fd, buf, 10);
11+
buf[ret] = '\0';
12+
13+
printf("Goodbye world! ret=%d buf=%s\n", ret, buf);
14+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#include <errno.h>
2+
#include <lind_syscall.h>
3+
4+
#include <assert.h>
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <sys/types.h>
8+
#include <sys/wait.h>
9+
#include <unistd.h>
10+
11+
// Dispatcher function
12+
int pass_fptr_to_wt(uint64_t fn_ptr_uint, uint64_t cageid, uint64_t arg1,
13+
uint64_t arg1cage, uint64_t arg2, uint64_t arg2cage,
14+
uint64_t arg3, uint64_t arg3cage, uint64_t arg4,
15+
uint64_t arg4cage, uint64_t arg5, uint64_t arg5cage,
16+
uint64_t arg6, uint64_t arg6cage) {
17+
if (fn_ptr_uint == 0) {
18+
fprintf(stderr,
19+
"[Grate|diff-cage-args] Invalid function ptr\n");
20+
assert(0);
21+
}
22+
23+
printf("[Grate|diff-cage-args] Handling function ptr: %llu from cage: "
24+
"%llu\n",
25+
fn_ptr_uint, cageid);
26+
27+
int (*fn)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
28+
uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
29+
uint64_t) =
30+
(int (*)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
31+
uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
32+
uint64_t))(uintptr_t)fn_ptr_uint;
33+
34+
return fn(cageid, arg1, arg1cage, arg2, arg2cage, arg3, arg3cage, arg4,
35+
arg4cage, arg5, arg5cage, arg6, arg6cage);
36+
}
37+
38+
int read_grate(uint64_t grateid, uint64_t arg1, uint64_t arg1cage,
39+
uint64_t arg2, uint64_t arg2cage, uint64_t arg3,
40+
uint64_t arg3cage, uint64_t arg4, uint64_t arg4cage,
41+
uint64_t arg5, uint64_t arg5cage, uint64_t arg6,
42+
uint64_t arg6cage) {
43+
int thiscage = getpid();
44+
int cageid = arg1cage;
45+
46+
int fd = (int)arg1;
47+
int count = (size_t)arg3;
48+
49+
ssize_t ret = 4321;
50+
51+
char buf[11] = "helloworld";
52+
53+
copy_data_between_cages(thiscage, arg2cage, (uint64_t)buf, thiscage,
54+
arg2, arg2cage, count,
55+
0 // Use copytype 0 so read exactly count
56+
// bytes instead of stopping at '\0'
57+
);
58+
59+
return ret;
60+
}
61+
62+
int open_grate(uint64_t cageid, uint64_t arg1, uint64_t arg1cage, uint64_t arg2,
63+
uint64_t arg2cage, uint64_t arg3, uint64_t arg3cage,
64+
uint64_t arg4, uint64_t arg4cage, uint64_t arg5,
65+
uint64_t arg5cage, uint64_t arg6, uint64_t arg6cage) {
66+
printf(
67+
"[Grate|diff-cage-args] In open_grate %d handler for cage: %llu\n",
68+
getpid(), cageid);
69+
70+
int self_grate_id = getpid();
71+
72+
// Overwrite the path supplied to open with a different path.
73+
char new_path[20] = "/tmp/redirected.txt";
74+
75+
int ret = make_threei_call(
76+
2, 0, self_grate_id, arg1cage,
77+
// We need to modify the cageid here to indicate that we want the
78+
// address translated.
79+
(uint64_t)&new_path, self_grate_id | (1ULL << 63), arg2, arg2cage,
80+
arg3, arg3cage, arg4, arg4cage, arg5, arg5cage, arg6, arg6cage,
81+
0 // we will handle the errno in this grate instead of translating
82+
// it to
83+
);
84+
85+
return ret;
86+
}
87+
88+
// Main function will always be same in all grates
89+
int main(int argc, char *argv[]) {
90+
// Should be at least one input (at least one grate file and one cage
91+
// file)
92+
if (argc < 2) {
93+
fprintf(stderr, "Usage: %s <cage_file> <grate_file>\n",
94+
argv[0]);
95+
assert(0);
96+
}
97+
98+
int grateid = getpid();
99+
100+
pid_t pid = fork();
101+
if (pid < 0) {
102+
perror("fork failed");
103+
assert(0);
104+
} else if (pid == 0) {
105+
int cageid = getpid();
106+
107+
// This is to test whether we can use arg, argcage from
108+
// different cages.
109+
uint64_t fn_ptr_addr = (uint64_t)(uintptr_t)&open_grate;
110+
int ret = register_handler(cageid, 2, grateid, fn_ptr_addr);
111+
112+
// This is to check copy_data for regression.
113+
fn_ptr_addr = (uint64_t)(uintptr_t)&read_grate;
114+
ret = register_handler(cageid, 0, grateid, fn_ptr_addr);
115+
116+
if (execv(argv[1], &argv[1]) == -1) {
117+
perror("execv failed");
118+
assert(0);
119+
}
120+
}
121+
122+
int status;
123+
int failed = 0;
124+
while (wait(&status) > 0) {
125+
if (status != 0) {
126+
fprintf(stderr,
127+
"[Grate|diff-cage-args] FAIL: child exited "
128+
"with status %d\n",
129+
status);
130+
assert(0);
131+
}
132+
}
133+
134+
printf("[Grate|diff-cage-args] PASS\n");
135+
return 0;
136+
}

0 commit comments

Comments
 (0)