Skip to content

Commit ff9bd74

Browse files
committed
fix assumptions about how fd_prestat_get may be called
The current implementation of `fd_prestat_get` does not appears to handle the following cases properly: - fd_prestat_get is called on the same file descriptor again - fd_prestat_get is called on stdio file descriptors (fd < 3) - fd_prestat_get is called in non sequential order of file descriptors
1 parent 087363a commit ff9bd74

3 files changed

Lines changed: 17 additions & 12 deletions

File tree

wasm-wasi-core/src/common/process.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ export abstract class WasiProcess {
242242

243243
this.environmentService = EnvironmentWasiService.create(
244244
this.fileDescriptors, this.programName,
245-
this.preOpenDirectories.entries(), options
245+
Array.from(this.preOpenDirectories.entries()), options
246246
);
247247
this.processService = {
248248
proc_exit: async (_memory, exitCode: exitcode) => {

wasm-wasi-core/src/common/service.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,13 @@ export interface EnvironmentOptions extends Omit<ProcessOptions, 'args' | 'trace
191191
}
192192

193193
export namespace EnvironmentWasiService {
194-
export function create(fileDescriptors: FileDescriptors, programName: string, preStats: IterableIterator<[string, DeviceDriver]>, options: EnvironmentOptions): EnvironmentWasiService {
194+
export function create(fileDescriptors: FileDescriptors, programName: string, preStats: [string, DeviceDriver][], options: EnvironmentOptions): EnvironmentWasiService {
195195

196196
const $encoder: RAL.TextEncoder = RAL().TextEncoder.create(options?.encoding);
197197
const $preStatDirnames: Map<fd, string> = new Map();
198198

199+
fileDescriptors.switchToRunning(3 + preStats.length);
200+
199201
const result: EnvironmentWasiService = {
200202
args_sizes_get: (memory: ArrayBuffer, argvCount_ptr: ptr<u32>, argvBufSize_ptr: ptr<u32>): Promise<errno> => {
201203
let count = 0;
@@ -262,16 +264,19 @@ export namespace EnvironmentWasiService {
262264
},
263265
fd_prestat_get: async (memory: ArrayBuffer, fd: fd, bufPtr: ptr<prestat>): Promise<errno> => {
264266
try {
265-
const next = preStats.next();
266-
if (next.done === true) {
267-
fileDescriptors.switchToRunning(fd);
267+
if (fd < 3) {
268+
return Errno.badf;
269+
}
270+
if (fd - 3 >= preStats.length) {
268271
return Errno.badf;
269272
}
270-
const [ mountPoint, driver ] = next.value;
271-
const fileDescriptor = await driver.fd_create_prestat_fd(fd);
272-
fileDescriptors.add(fileDescriptor);
273-
fileDescriptors.setRoot(driver, fileDescriptor);
274-
$preStatDirnames.set(fileDescriptor.fd, mountPoint);
273+
const [ mountPoint, driver ] = preStats[fd - 3];
274+
if (!fileDescriptors.has(fd)) {
275+
const fileDescriptor = await driver.fd_create_prestat_fd(fd);
276+
fileDescriptors.add(fileDescriptor);
277+
fileDescriptors.setRoot(driver, fileDescriptor);
278+
$preStatDirnames.set(fileDescriptor.fd, mountPoint);
279+
}
275280
const view = new DataView(memory);
276281
const prestat = Prestat.create(view, bufPtr);
277282
prestat.preopentype = Preopentype.dir;
@@ -1124,7 +1129,7 @@ export namespace FileSystemService {
11241129
const clock = Clock.create();
11251130
return Object.assign(
11261131
{},
1127-
EnvironmentWasiService.create(fileDescriptors, 'virtualRootFileSystem', preOpens.entries(), {}),
1132+
EnvironmentWasiService.create(fileDescriptors, 'virtualRootFileSystem', Array.from(preOpens.entries()), {}),
11281133
DeviceWasiService.create(deviceDrivers, fileDescriptors, clock, virtualRootFileSystem, options)
11291134
);
11301135
}

wasm-wasi-core/src/common/test/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export function createWasiService(workspaceContent: WorkspaceContent): WasiServi
9191

9292
const clock = Clock.create();
9393
const fileSystemService = DeviceWasiService.create(deviceDrivers, fileDescriptors, clock, undefined, options);
94-
const environmentService = EnvironmentWasiService.create(fileDescriptors, 'testApp', preOpenDirectories.entries(), options);
94+
const environmentService = EnvironmentWasiService.create(fileDescriptors, 'testApp', Array.from(preOpenDirectories.entries()), options);
9595
const clockService = ClockWasiService.create(clock);
9696
const result: WasiService = Object.assign({}, NoSysWasiService, environmentService, clockService, fileSystemService);
9797
return result;

0 commit comments

Comments
 (0)