Linux Laptop Locking

If you wrote your own systemd unit to lock your laptop on suspend, you might want to double-check its behavior. The top two Google results for “systemd lock laptop on suspend” both provide examples that lock on resume, not suspend.1 This is a security risk.

How did I discover this? A few months ago, I switched to Sway, a tiling window manager similar to i3.2 Like i3, Sway requires a significant amount of configuration to get behaviors that Mac users take for granted.

One feature I wanted was to lock the screen when I closed my laptop’s lid. Like any lazy programmer I googled some terms, consulted the first Stack Exchange link, and created the necessary systemd unit:

[Unit]
Description=Lock the screen

[Service]
User=ggreer
Environment=DISPLAY=:0
ExecStart=/usr/local/bin/lock-screen

[Install]
WantedBy=suspend.target

This is a pretty straightforward unit. On suspend, run lock-screen. Unfortunately, it’s wrong.

A few weeks after adding the unit, I opened my laptop and stared at an unlocked screen. Immediately, I delved into logs to figure out how this happened. It wasn’t long before I found the answer: The system had failed to suspend because of an sshfs mount. This was a double surprise. I didn’t know that:

  1. A non-root process could prevent the kernel from suspending.
  2. My systemd unit was locking after suspend instead of before.

The fix didn’t require changing much:

 [Unit]
 Description=Lock the screen
+Before=sleep.target
 
 [Service]
 User=ggreer
 Environment=DISPLAY=:0
 ExecStart=/usr/local/bin/lock-screen
 
 [Install]
-WantedBy=suspend.target
+WantedBy=sleep.target

Adding “Before=...” forces systemd to wait for lock-screen to start before suspending.3 Using sleep.target is a little more robust, as suspend.target only covers suspending to RAM. Sleep covers suspending to RAM, suspending to disk, and hybrid sleep.

If you’re running a highly-customized Linux GUI, you’ll probably never be as secure as stock Fedora or Ubuntu. A single mistake (such as the one I made) can leave your system totally vulnerable. Less popular window managers often lack basic exploit mitigation techniques such as clearing passwords from memory.


  1. As of 2018-01-01, the top two results are an Arch Linux forum post and a Stack Exchange answer. Both use WantedBy=suspend.target and omit Before=...

  2. The release of Ubuntu 17.10 switched from Unity to Gnome Shell, making the user interface a nightmare. It’s like they tried their hardest to annoy users. For example, joining a wifi network went from two clicks to five. I’d rather deal with stupid config files and alpha-quality tiling window managers than continue to use Gnome Shell. 

  3. More information on the behavior of Before= and After= can be found in systemd’s unit documentation



When commenting, remember: Is it true? Is it necessary? Is it kind?