Long delay during login when MAC spoofing has failed
When testing !70 (merged) thanks to the new debug=test_mac_spoof_panic
boot option, I noticed an unusually long delay (at least 1 minute) between the time I click "Start Tails" in the Welcome Screen, and the time when the desktop is displayed.
I see that /etc/gdm3/PostLogin/Default
calls tails-unblock-network
, which triggers MAC spoofing and waits for all udev triggers to have run. The main such udev trigger is tails-spoof-mac
, which waits for the amnesia
user's ibus-daemon
process to be running, then waits 10 seconds, then displays a notification (and since !48 (merged) we wait for the notification subprocess to exit).
08:36:50 amnesia spoof-mac[4537]: Trying to spoof MAC address of NIC eth0... 08:36:50 amnesia spoof-mac[4617]: Failed to spoof MAC address of NIC eth0. Going into panic mode. 08:36:51 amnesia spoof-mac[5077]: Successfully unloaded module virtio_net of NIC eth0. 08:37:50 amnesia systemd-udevd[379]: eth0: Worker [4437] processing SEQNUM=3222 is taking a long time 08:37:50 amnesia systemd-udevd[4437]: Spawned process '/usr/local/lib/tails-spoof-mac eth0' [4508] is taking longer than 59s to complete 08:38:51 amnesia systemd[1]: systemd-udev-settle.service: Main process exited, code=exited, status=1/FAILURE 08:38:51 amnesia systemd[1]: systemd-udev-settle.service: Failed with result 'exit-code'. 08:38:51 amnesia systemd[1]: Failed to start udev Wait for Complete Device Initialization. 08:38:51 amnesia gdm-session-worker[4395]: Job for systemd-udev-settle.service failed because the control process exited with error code. 08:38:51 amnesia gdm-session-worker[4395]: See "systemctl status systemd-udev-settle.service" and "journalctl -xe" for details. 08:38:51 amnesia gdm-session-worker[4395]: tails-unblock-network has exited (status=1).
And only after that, X.Org and ibus-daemon
are started for the amnesia
user.
So it seems to me that we could have a deadlock, that udev solves by timeout'ing: we're waiting for a process (ibus-daemon
) that cannot possible be started until we've stopped waiting for it. What I don't fully understand is that I do see the "Network card eth0 disabled" notification, so notify_panic_failure "${nic}" "${nic_name}" &
was apparently not killed by udev, which contradicts what 39cc195e says.
Proposed fix
My current thinking is that instead of starting long-running blocking code from a udev trigger as a subprocess, we should move the notify_panic_*
bits to a systemd service in the user session, that tails-spoof-mac
would trigger startup of. This should fix the aforementioned potential deadlock and remove the delay this issue is about. This could look like:
- Add 2
systemd --user
unit templates (config/chroot_local-includes/usr/lib/systemd/user/tails-mac-spoof-failed-panic-{success,failure}@.service
), which would:-
not be enabled by default in the
52-update-rc.d
hook - take over the job of displaying the failure notification (what's done respectively in
notify_panic_success()
andnotify_panic_failure()
) - be
WantedBy=desktop.target
- be parameterized by the low-level name (e.g.
eth0
) of the network card whose MAC address could not be spoofed, i.e. callingget_name_of_nic
, so that if this part fails, it cannot possibly affect the MAC spoofing panic code path itself: it can only affect displaying the notification - also take over the responsibility of computing a nicer, user-visible name for the network card
-
not be enabled by default in the
- On MAC spoofing failure,
tails-spoof-mac
would instantiate and enable the one relevant unit template among those 2, with the name of the relevant network card as the parameter ⇒ when theamnesia
user'ssystemd --user
startsdesktop.target
, it will start this unit, which will display the notification.