From 24228010eb512edabde102831d3181426095b070 Mon Sep 17 00:00:00 2001 From: Martin Varmuza Date: Wed, 13 Nov 2024 15:54:20 +0100 Subject: [PATCH] fix(transport): fix node bridge segfault when disconnected while button request displayed on device --- packages/transport/src/api/usb.ts | 19 ++++++++++++------- packages/transport/tests/apiUsb.test.ts | 2 ++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/transport/src/api/usb.ts b/packages/transport/src/api/usb.ts index c2b0821106f..449e7a95994 100644 --- a/packages/transport/src/api/usb.ts +++ b/packages/transport/src/api/usb.ts @@ -189,7 +189,7 @@ export class UsbApi extends AbstractApi { } public async read(path: string, signal?: AbortSignal) { - const device = this.findDevice(path); + const device = await this.findDevice(path); if (!device) { return this.error({ error: ERRORS.DEVICE_NOT_FOUND }); } @@ -227,7 +227,7 @@ export class UsbApi extends AbstractApi { } public async write(path: string, buffer: Buffer, signal?: AbortSignal) { - const device = this.findDevice(path); + const device = await this.findDevice(path); if (!device) { return this.error({ error: ERRORS.DEVICE_NOT_FOUND }); } @@ -285,7 +285,7 @@ export class UsbApi extends AbstractApi { } private async openInternal(path: string, first: boolean, signal?: AbortSignal) { - const device = this.findDevice(path); + const device = await this.findDevice(path); if (!device) { return this.error({ error: ERRORS.DEVICE_NOT_FOUND }); } @@ -354,7 +354,7 @@ export class UsbApi extends AbstractApi { } public async closeDevice(path: string) { - let device = this.findDevice(path); + let device = await this.findDevice(path, true); if (!device) { return this.error({ error: ERRORS.DEVICE_NOT_FOUND }); } @@ -364,6 +364,8 @@ export class UsbApi extends AbstractApi { if (device.opened) { if (!this.debugLink) { try { + // https://github.com/trezor/trezor-suite/issues/15336 + await createTimeoutPromise(500); // NOTE: `device.reset()` interrupts transfers for all interfaces (debugLink and normal) await device.reset(); } catch (err) { @@ -374,7 +376,7 @@ export class UsbApi extends AbstractApi { } } - device = this.findDevice(path); + device = await this.findDevice(path); if (device?.opened) { try { const interfaceId = this.debugLink ? DEBUGLINK_INTERFACE_ID : INTERFACE_ID; @@ -391,7 +393,7 @@ export class UsbApi extends AbstractApi { // ignore } } - device = this.findDevice(path); + device = await this.findDevice(path); if (device?.opened) { try { this.logger?.debug(`usb: device.close`); @@ -414,7 +416,10 @@ export class UsbApi extends AbstractApi { return this.success(undefined); } - private findDevice(path: string) { + private async findDevice(path: string, refresh = false) { + if (refresh) { + await this.enumerate(); + } const device = this.devices.find(d => d.path === path); if (!device) { return; diff --git a/packages/transport/tests/apiUsb.test.ts b/packages/transport/tests/apiUsb.test.ts index 281b1b498c7..87f8afcc7d0 100644 --- a/packages/transport/tests/apiUsb.test.ts +++ b/packages/transport/tests/apiUsb.test.ts @@ -54,6 +54,7 @@ describe('api/usb', () => { const abortController = new AbortController(); await api.enumerate(abortController.signal); const promise = api.read('123', abortController.signal); + await Promise.resolve(); abortController.abort(); const result = await promise; @@ -82,6 +83,7 @@ describe('api/usb', () => { const abortController = new AbortController(); await api.enumerate(abortController.signal); const promise = api.write('123', Buffer.alloc(api.chunkSize), abortController.signal); + await Promise.resolve(); abortController.abort(); const result = await promise;