trezor / trezord-go

:smiling_imp: Trezor Communication Daemon (written in Go)
GNU Lesser General Public License v3.0
244 stars 146 forks source link

trezord-go 2.0.2* interacts unexpectedly in a Qubes Debian VM #162

Closed farrilis closed 5 years ago

farrilis commented 5 years ago

Qubes OS components:

Trezor components:

Steps to reproduce

  1. Run trezord-go in trezor-VM terminal
  2. Attach Trezor 1 to trezor-VM from USB-VM (sys-usb)
  3. Run trezorctl get-features in trezor-VM
  4. TransportException 400: device not found error message
  5. Ctrl+C to terminate trezord-go
  6. Now run any trezorctl command, no errors
Full error line from trezorctl: File "/usr/lib/python3/dist-packages/trezorlib/transport/bridge.py", line 45, in call_bridge raise TransportException(error_str) trezorlib.transport.TransportException: trezord: acquire/lib01/null failed with code 400: device not found
trezord-go error output: 127.0.0.1 - - [30/Apr/2019:14:15:13 +0200] "POST /enumerate HTTP/1.1" 200 98 [6.078580 : 14:15:13] 127.0.0.1 - - [30/Apr/2019:14:15:13 +0200] "POST /enumerate HTTP/1.1" 200 98 POST /acquire/lib01/null [6.109705 : 14:15:13] POST /acquire/lib01/null [6.109777 : 14:15:13] core - acquire - locking sessionsMutex [6.109784 : 14:15:13] core - acquire - input path lib01 prev [6.109789 : 14:15:13] core - acquire - actually previous [6.109793 : 14:15:13] core - acquire - trying to connect [6.109798 : 14:15:13] core - tryConnect - try number 0 [6.109803 : 14:15:13] libusb - connect - low level enumerating [6.109822 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_list] [6.109837 : 14:15:13] libusb - connect - low level enumerating done [6.109889 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_descriptor] before memcpy [6.109900 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_descriptor] after memcpy [6.109906 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_descriptor] return [6.109947 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_descriptor] before memcpy [6.109953 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_descriptor] after memcpy [6.109961 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_descriptor] return [6.109968 : 14:15:13] [0000046c] libusb: debug [libusb_get_active_config_descriptor] start, call backend first [6.110033 : 14:15:13] [0000046c] libusb: debug [libusb_get_active_config_descriptor] done [6.110041 : 14:15:13] [0000046c] libusb: debug [libusb_get_active_config_descriptor] parse [6.110046 : 14:15:13] [0000046c] libusb: debug [libusb_get_active_config_descriptor] malloc [6.110051 : 14:15:13] [0000046c] libusb: debug [libusb_get_active_config_descriptor] call backend 2 [6.110068 : 14:15:13] [0000046c] libusb: debug [libusb_get_active_config_descriptor] raw_desc_to_config [6.110077 : 14:15:13] [0000046c] libusb: debug [libusb_get_active_config_descriptor] free [6.110083 : 14:15:13] [0000046c] libusb: debug [libusb_get_active_config_descriptor] return [6.110135 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_descriptor] before memcpy [6.110142 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_descriptor] after memcpy [6.110148 : 14:15:13] [0000046c] libusb: debug [libusb_get_device_descriptor] return [6.110152 : 14:15:13] libusb - connect - low level [6.110161 : 14:15:13] [0000046c] libusb: debug [libusb_open] open 1.2 [6.110246 : 14:15:13] [0000046c] libusb: debug [usbi_add_pollfd] add fd 11 events 4 [6.110260 : 14:15:13] libusb - connect - reset [6.110267 : 14:15:13] [0000046c] libusb: debug [libusb_reset_device] [9.673922 : 14:15:17] [0000046d] libusb: debug [linux_netlink_parse] unknown device action unbind [9.676520 : 14:15:17] [0000046d] libusb: debug [linux_netlink_parse] unknown device action unbind [9.676565 : 14:15:17] [0000046d] libusb: debug [linux_netlink_parse] unknown device action unbind [9.676589 : 14:15:17] [0000046d] libusb: debug [linux_netlink_read_message] netlink hotplug found device busnum: 1, devaddr: 2, sys_name: 1-1, removed: yes [9.677538 : 14:15:17] Warning: error at device reset: LIBUSB_ERROR_NOT_FOUND [9.677576 : 14:15:17] [0000046c] libusb: debug [libusb_get_configuration] [9.677605 : 14:15:17] [0000046c] libusb: error [_open_sysfs_attr] open /sys/bus /usb/devices/1-1/bConfigurationValue failed ret=-1 errno=2 [9.677664 : 14:15:17] libusb - connect - current configuration err LIBUSB_ERROR_IO [9.677674 : 14:15:17] libusb - connect - set_configuration [9.677681 : 14:15:17] [0000046c] libusb: debug [libusb_set_configuration] configuration 1 [9.677696 : 14:15:17] Warning: error at configuration set: LIBUSB_ERROR_NO_DEVICE [9.677708 : 14:15:17] [0000046c] libusb: debug [libusb_get_configuration] [9.677748 : 14:15:17] [0000046c] libusb: error [_open_sysfs_attr] open /sys/bus/usb/devices/1-1/bConfigurationValue failed ret=-1 errno=2 [9.677760 : 14:15:17] libusb - connect - current configuration err LIBUSB_ERROR_IO [9.677764 : 14:15:17] libusb - connect - detecting kernel driver [9.677775 : 14:15:17] [0000046c] libusb: debug [libusb_kernel_driver_active] interface 0 [9.677780 : 14:15:17] libusb - connect - detecting kernel driver failed [9.677791 : 14:15:17] [0000046c] libusb: debug [libusb_close] [9.677810 : 14:15:17] [0000046c] libusb: debug [usbi_remove_pollfd] remove fd 11 [9.677828 : 14:15:17] libusb - connect - freeing device list [9.677838 : 14:15:17] libusb - connect - freeing device list done [9.677879 : 14:15:17] core - tryConnect - sleeping [9.791022 : 14:15:17] core - tryConnect - try number 1 [9.791053 : 14:15:17] libusb - connect - low level enumerating

Previously (i.e. yesterday), python-trezor 0.10.1 and trezord-go 2.0.16 worked in a VM based on the same template with trezord http server running, which I believe is the expected behaviour. Now that the T1 is using 1.8.0 fw, trezord-go 2.0.25 is the minimum device driver, and going back to previous firmware is not an option as a newer bootloader is bundled with 1.8.0 fw

To clarify, all python-trezor commands work perfectly once the trezord-go process is terminated. I've confirmed that wipe-device, recovery-device and get-address work as expected, but only if trezord-go is not running!

This happens consistently, I was mistaken to say this issue is intermittent in a previous comment (forgot the T1 was wiped, which seemed like intermittent functionality)

prusnak commented 5 years ago

Does this happen on Debian 9 running on bare metal?

farrilis commented 5 years ago

@prusnak, I don't use my Trezor with online machines. python-trezor setup unfortunately requires internet access for pip install (which is already vulnerable to MITM attacks, as pip packages are not signed or hash verified).

I don't want to be the person about which people say: "farrilis was very unlucky, no-one could have predicted that attack"

If you have an idea to troubleshoot the issue using bare metal Debian 9, I could move the python-trezor installation to bare metal Debian 9 on the same hardware, run from Live CD with no network. The OS wouldn't be fully patched (but there are always ISOs of a recent snapshot of up-to-date Debian)

I'm open to other suggestions also, it would be great to get Trezor and Qubes working together properly for everyone's benefit

farrilis commented 5 years ago

I think I may have solved this

  1. I disabled trezord.service, and moved the /usr/bin/trezord-go binary in the VM template (no trezord-go process exists in the trezor-VM when it boots
  2. trezorctl functions perfectly

Conclusion: trezord-go is not required for the Trezor 1 using WebUSB to communicate with python-trezor, if there is an appropriate USB proxy in place (such as in a standard Qubes VM)

Does this sound correct to Satoshi Labs devs? Because that's what seems to be happening

prusnak commented 5 years ago

Yes. python-trezor communicates directly with the device when trezord is not running.

Btw. have you tried this guide here: https://wiki.trezor.io/Qubes_OS ?

If you have any suggestions on how to improve that, please let us know.

farrilis commented 5 years ago

Btw. have you tried this guide here: https://wiki.trezor.io/Qubes_OS ?

I did not know about that.

Suggestions:

  1. Explicitly state on python-trezor page "Do not use TREZOR bridge"
  2. Explicitly state on Trezor Bridge section of Setting up Trezor that Bridge is only need for the Web Wallet service or for HIDAPI Trezors
  3. (Maybe) Explicitly state on "Command line tools" section of Setting up Trezor that Bridge is only needed for HIDAPI
  4. Clarify the same issue at https://wiki.trezor.io/Qubes_OS (trezord-go not needed for WebUSB firmware)
  5. A link to Qubes guide in the wiki. Maybe the Security page would be the right place
farrilis commented 5 years ago

So closing this, I misidentified the problem

prusnak commented 5 years ago

@farrilis Well, trezord-go IS required if you intend to use Trezor from Firefox, so it is recommended. Thus I am against avoiding using the bridge, which eliminates suggestions 1-4.

I added new section Guides under Security wiki page including a link to the Qubes OS page. Thanks

farrilis commented 5 years ago

I added new section Guides under Security wiki page including a link to the Qubes OS page. Thanks

Yes, that will be useful

Maybe it could be useful to state at https://github.com/trezor/python-trezor/blob/master/README.md that trezord-go can (or will?) prevent WebUSB devices connecting to python-trezor, instead of recommending against using TREZOR Bridge altogether

prusnak commented 5 years ago

python-trezor WILL try to use Bridge first. Only if it is not available it will try connecting directly.