It’s worth noting that “Wayland does not support screen savers” isn’t strictly true. It just doesn’t have any protocols which allow any old Wayland client to be a screen saver the way X (sort of) allows any X client to be a screen saver. GNOME, for example, could build a screen saver in to Mutter.
Of course jwz knows this, and I’m guessing it’s exactly what he means by “… it does not have any provision that allows screen savers to even exist in any meaningful way”. Wayland does not have any provisions that allows separate screen saver programs to exist in a meaningful way. I just want people to not end up with the impression that Wayland can’t be used to make a system which has screen saver support; the main reason GNOME doesn’t have a screen saver on Wayland is that GNOME doesn’t want/prioritize it.
As for the main topic of the article, it would be cool if there were standard ways to implement both screen locker programs and screen saver programs which work across a wide range of Wayland compositors. And this brief specification for how they should work seem alright. There difficult part is going to be this:
When it it time to start drawing, that screen saver manager just needs to know set of rectangles into which graphics should be drawn, whether that’s a set of window IDs, or geometry specifications, or whatever.
Wayland clients can’t draw into windows they don’t own, and they can’t absolutely position their own windows. You’d probably want something like the wlroots layer-shell protocol to open a window on a specific monitor. Another complication is that the set of “geometry specifications” changes dynamically as monitors are connected and disconnected, which can be a nasty source of bugs.
When it it time to start drawing, that screen saver manager just needs to know set of rectangles into which graphics should be drawn, whether that’s a set of window IDs, or geometry specifications, or whatever.
Wayland clients can’t draw into windows they don’t own, and they can’t absolutely position their own windows. You’d probably want something like the wlroots layer-shell protocol to open a window on a specific monitor. Another complication is that the set of “geometry specifications” changes dynamically as monitors are connected and disconnected, which can be a nasty source of bugs.
The session-lock protocol exists for this purpose (disclaimer, I wrote it) and avoids the “I told you so” problem where the sreenlocker/screensaver client crashing leaves the session unlocked.
However, as I am the world’s foremost expert on screen savers on Unix-like operating systems
Love the humility. (but it is a warranted statement for sure).
However I’d be curious how a truly grumpy OG like JWZ would interact with the mostly young Wayland committee for setting up an extension for screen saving.
There was a proposal for one many years ago but I’m not sure what state it’s in anymore.
I try out some Wayland compositors every six months or so as part of my (by now probably futile) “is desktop Linux still dead” check-up, and last time I had a go at it back in June-ish, I played with swaylock-effects a bit, which suggests it’s possible to piggyback some graphics onto the session-lock protocol.
Unfortunately, the session-lock protocol is… pretty generous in terms of what action it prescribes from compositors, so I’m not sure how feasible it would be to write something that’s both as flexible as XScreensaver and compatible across enough compositors to be useful. It allows for substantial changes in behaviour on the compositor side while still remaining technically in compliance. Keeping a locker like XScreensaver a separate application from the WM/desktop environment/whatever was feasible in X11’s landscape but, based on the looks of that spec, it’s probably not feasible across Wayland compositors, even if they technically comply (to a spec that I think only wlroots implements).
But frankly I think the biggest obstacle would be cultural in nature: writing screen lockers for X11 inevitably leads to a very grim view of life, the universe and everything, and a surprising proportion of people working on modern Wayland compositors are too young to have ever used a screensaver.
(FWIW I’m also… a bit scared about some of these provisions, like the one allowing the compositor to wait for the client to create and render lock surfaces before sending the locked event.)
Unfortunately, the session-lock protocol is… pretty generous in terms of what action it prescribes from compositors, so I’m not sure how feasible it would be to write something that’s both as flexible as XScreensaver and compatible across enough compositors to be useful.
Do you have an example of how two compositors could differ in behavior in a way that makes it impossible to write portable clients?
(FWIW I’m also… a bit scared about some of these provisions, like the one allowing the compositor to wait for the client to create and render lock surfaces before sending the locked event.)
What exactly is scaring you about that? It’s an optional bit of extra complexity that may be implemented on the compositor slide to maintain Wayland’s “frame perfection” ideal and not show unnecessary blank frames. Clients shouldn’t really need to do anything special here.
Overall, I’m quite confident that the session-lock protocol is a meaningful step up in security over what compositor were doing before I wrote it. As in all non-trivial software endeavors there is of course room for improvement.
Do you have an example of how two compositors could differ in behavior in a way that makes it impossible to write portable clients?
It sounds like I should clarify that “I’m not sure how feasible” it is in terms of implementation effort, not (theoretical) technical feasibility. The part that does the actual screen locking in Xscreensaver is actually pretty small, at least compared to how much server-side weirdness it needs to accomodate (as I’m sure you’ve long found out, given that session-lock avoids most, if not all of X11’s locking-related problems, X11 is really awful at locking screens, it’s like it was deliberately designed to not lock them).
For one thing, if I’m reading this right, it’s possible for a compositor to forbid a third-party client from even working in the first place:
The compositor may choose to restrict this protocol to a special client launched by the compositor itself or expose it to all privileged clients, this is compositor policy.
so even a compliant client would not necessarily be allowed to run across all compliant compositors. But I don’t mean that it’s impossible to write compliant clients, just that there’s more variability allowed on the compositor end than in a comparable X11 implementation. E.g. they may or may not recover a lost session, and the exact (secure) manner in which that’s done is compositor-specific, and may involve the compositor spawning a new client. This accomodates more variability than Xscreensaver’s currently design has to accommodate for X11.
On top of that, a program comparable to Xscreensaver would have to implement not only session-lock, which I think is only properly supported by wlroots? but also whatever Mutter and KWin use, and whatever other compositors will use in the future. Xscreensaver does have some hacks specific to e.g. both KDE and Gnome, mostly in the systemd shim in order to work around the quirks of the screensaver inhibit mechanism, but must of the code that achieves the actual locking is common to anything you may be running on the X side. There’s a lot of system-specific code of course (e.g. in unlocking methods) but that’s not related to the display server per se and would presumably have to be replicated by a comparable Wayland implementation (modulo things like pre-PAM Kerberos code which I think the British Museum should just call dibs on already).
What exactly is scaring you about that? It’s an optional bit of extra complexity that may be implemented on the compositor slide to maintain Wayland’s “frame perfection” ideal and not show unnecessary blank frames. Clients shouldn’t really need to do anything special here.
I understand that’s a necessary trade-off, both because it needs to accomodate a wide range of compositor architectures and because it needs to fit in Wayland’s “frame perfection” idea. What scares me is that protocol-allowed timeouts are occasionally misused in practice – i.e. not that a sound, compliant implementation has a specific weakness, but the kind of bugs a bad implementation could have.
E.g. it sounds like one could race the locker for resources and prevent it from allocating the necessary resources and rendering the first frames, thus delaying the actual locking moment until the implementation-specified timeout. That’s one timing bug away from never (or hours), or one unreasonable value away from a long enough window to allow exploiting other bugs in the locker or the compositor, in the kind of code that I bet won’t see much testing on compositor implementations. (Note that I am, once again, thinking of an implementation comparable to Xscreensaver: some of its screensavers (“hacks”) are pretty ellaborate, they involve pretty heavy 3D graphics, one has a full 6502 emulator with CRT emulation shaders etc. – so they legit need a lot of resources).
I know it’s not something you have control over at the protocol end. Even assuming a bug like that occurs in a popular compositor, and it’s trivial to trigger, I still think you’re right when saying that
the session-lock protocol is a meaningful step up in security
both compared to what compositors were doing before it and compared to X11. Hypothetical bugs in an implementation are exactly that, hypothetical, whereas current flaws in other locking protocols (and, God, X11) are very real. It’s just decades of exposure to (mostlly X11) Linux desktop code has conditioned me to think less in terms of “how does this help” and more in terms of “how will this be misused to work around application bugs”.
Hypothetical bugs in an implementation are exactly that, hypothetical, whereas current flaws in other locking protocols (and, God, X11) are very real.
You’re quite right that this timeout mechanism for the purposes of frame perfection is the most complex part of the protocol and therefore the most likely cause of bugs and vulnerabilities in the compositor implementation. In the end, the user must trust their compositor implementation to have any expectation of security.
The most secure thing a compositor could do would be to forego frame perfection and immediately blank all monitors until the session lock client has rendered its first frames.
For what it’s worth, I opted for the more complex but frame-perfect option for my compositor, river. The implementation has thus far seen no bugs that allowed access to a session that should have been locked. There were however multiple assertion failures hit by users in the wild as I worked out all the edge cases inherent to asynchronous programming in the early days of the protocol implementation. It’s been a while (>6 months?) since I’ve had any report of a bug relating to river’s session-lock implementation.
Right, I suspect any exploitable behaviour there hinges on associated bugs (or poor timeout choices) in the compositor, not at the screen lock end. This situation is somewhat reversed compared to XScreensaver (where the display server and the WM don’t really get to do anything about the screen getting locked) but does have the distinct advantage that the compositor can (modulo bugs) do the right thing regardless of what the locker does. In X11 land, if xscreensaver crashes when the locker is initialised, or can’t grab focus or whatever, the session remains unlocked (or at least remained unlocked at some point, or on some configurations, I’m sure there some setup where you get that awful “Press Ctrl+Alt+F1 and restart the login session” message nowadays).
I’m going to pre-emptively apologize for spamming your inbox, I know I’ve already posted in this thread but that message is old enough that netiquette would demand I don’t edit it, and this one’s somewhat oblique to it. I’ve re-read the specs more closely (my interest in Wayland waned, uh, years before session-lock was proposed, so I’ve only learned about it by browsing Github a few months back) and I have a bunch of questions now :-D.
How does session-lock handle screensavers that want to apply desktop effects (e.g. like Cityscape?). I expect the screen locker program can’t just be granted arbitrary “screenshotting” privileges forever, and should only be allowed to grab an image of the desktop, or some arbitrary surface, when locking the screen. However, when the compositor delivers the lock message, it’s also supposed to blank all surfaces (except for some compositor-specific ones). Is there a way for all compliant clients to request that, or would that entail writing compositor-specific code?
If the client dies while it’s allocating resources, while the compositor is waiting for it to create and render session lock surface but before the locked message has been delivered, is it possible to distinguish between that and an input-triggered abort? I.e. can the compositor easily determine if the screen locker crashed while initializing and keep the session lock or an input event arrived just in time to trigger a lock abort? Or is this sequence atomic (i.e. once it’s started, locking is guaranteed to always succeed, unless the client crashes) so it’s a non-problem?
Is there any support for inhibiting the screen locker in session-lock (for a set period, or while a program is running etc.)? This is one of the things that XScreensaver really struggles with (as X11 makes no specific provisions for screen locking and the existing systemd-based mechanism is completely inadequate).
I’m going to pre-emptively apologize for spamming your inbox
No worries!
How does session-lock handle screensavers that want to apply desktop effects…
This is not something currently handled by the session-lock protocol. It could be added to the protocol in a backwards compatible way by adding an event which provides the client with a screenshot of all monitors at the time which is sent by the compositor in response to the ext_session_lock_manager_v1.lock request. This is not something I personally have a use-case for or interest in working on though.
If the client dies while it’s allocating resources, while the compositor is waiting for it to create and render session lock surface but before the locked message has been delivered, is it possible to distinguish between that and an input-triggered abort? I.e. can the compositor easily determine if the screen locker crashed while initializing and keep the session lock or an input event arrived just in time to trigger a lock abort? Or is this sequence atomic (i.e. once it’s started, locking is guaranteed to always succeed, unless the client crashes) so it’s a non-problem?
This is atomic, once the compositor receives the ext_session_lock_manager_v1.lock request the session is locked even if the client crashes right after sending it. Sending the lock request does not require the client to allocate any significant resources or render any surfaces.
Is there any support for inhibiting the screen locker in session-lock (for a set period, or while a program is running etc.)? This is one of the things that XScreensaver really struggles with (as X11 makes no specific provisions for screen locking and the existing systemd-based mechanism is completely inadequate).
This is out of scope of the session-lock protocol. There is however an idle-inhibit protocol that allows e.g. a video player to inform the compositor that idle should be inhibited while a video is playing. Compositors generally offer their own configuration options around when the session should be considered idle and allow disabling idle manually for a time frame. This kind of policy is something that’s intentionally not left up to clients on Wayland.
Love the humility. (but it is a warranted statement for sure).
May be veering off-topic, but: it’s delightful to see this sort of pride in print.
“Impostor syndrome” is definitely a real thing, and it’s very helpful to those suffering from it that people talk about it these days. And many people who aren’t impostors, but are early on their particular learning curves, feel happier talking about that than they did years ago when I was a junior.
But it gives me an emotional lift to see someone who is an expert in a field recognise that fact and call it out when relevant :)
It’s worth noting that “Wayland does not support screen savers” isn’t strictly true. It just doesn’t have any protocols which allow any old Wayland client to be a screen saver the way X (sort of) allows any X client to be a screen saver. GNOME, for example, could build a screen saver in to Mutter.
Of course jwz knows this, and I’m guessing it’s exactly what he means by “… it does not have any provision that allows screen savers to even exist in any meaningful way”. Wayland does not have any provisions that allows separate screen saver programs to exist in a meaningful way. I just want people to not end up with the impression that Wayland can’t be used to make a system which has screen saver support; the main reason GNOME doesn’t have a screen saver on Wayland is that GNOME doesn’t want/prioritize it.
As for the main topic of the article, it would be cool if there were standard ways to implement both screen locker programs and screen saver programs which work across a wide range of Wayland compositors. And this brief specification for how they should work seem alright. There difficult part is going to be this:
Wayland clients can’t draw into windows they don’t own, and they can’t absolutely position their own windows. You’d probably want something like the wlroots layer-shell protocol to open a window on a specific monitor. Another complication is that the set of “geometry specifications” changes dynamically as monitors are connected and disconnected, which can be a nasty source of bugs.
The session-lock protocol exists for this purpose (disclaimer, I wrote it) and avoids the “I told you so” problem where the sreenlocker/screensaver client crashing leaves the session unlocked.
Love the humility. (but it is a warranted statement for sure).
However I’d be curious how a truly grumpy OG like JWZ would interact with the mostly young Wayland committee for setting up an extension for screen saving.
There was a proposal for one many years ago but I’m not sure what state it’s in anymore.
I try out some Wayland compositors every six months or so as part of my (by now probably futile) “is desktop Linux still dead” check-up, and last time I had a go at it back in June-ish, I played with swaylock-effects a bit, which suggests it’s possible to piggyback some graphics onto the session-lock protocol.
Unfortunately, the session-lock protocol is… pretty generous in terms of what action it prescribes from compositors, so I’m not sure how feasible it would be to write something that’s both as flexible as XScreensaver and compatible across enough compositors to be useful. It allows for substantial changes in behaviour on the compositor side while still remaining technically in compliance. Keeping a locker like XScreensaver a separate application from the WM/desktop environment/whatever was feasible in X11’s landscape but, based on the looks of that spec, it’s probably not feasible across Wayland compositors, even if they technically comply (to a spec that I think only wlroots implements).
But frankly I think the biggest obstacle would be cultural in nature: writing screen lockers for X11 inevitably leads to a very grim view of life, the universe and everything, and a surprising proportion of people working on modern Wayland compositors are too young to have ever used a screensaver.
(FWIW I’m also… a bit scared about some of these provisions, like the one allowing the compositor to wait for the client to create and render lock surfaces before sending the locked event.)
(Disclaimer, I wrote the session-lock protocol)
Do you have an example of how two compositors could differ in behavior in a way that makes it impossible to write portable clients?
What exactly is scaring you about that? It’s an optional bit of extra complexity that may be implemented on the compositor slide to maintain Wayland’s “frame perfection” ideal and not show unnecessary blank frames. Clients shouldn’t really need to do anything special here.
Overall, I’m quite confident that the session-lock protocol is a meaningful step up in security over what compositor were doing before I wrote it. As in all non-trivial software endeavors there is of course room for improvement.
It sounds like I should clarify that “I’m not sure how feasible” it is in terms of implementation effort, not (theoretical) technical feasibility. The part that does the actual screen locking in Xscreensaver is actually pretty small, at least compared to how much server-side weirdness it needs to accomodate (as I’m sure you’ve long found out, given that session-lock avoids most, if not all of X11’s locking-related problems, X11 is really awful at locking screens, it’s like it was deliberately designed to not lock them).
For one thing, if I’m reading this right, it’s possible for a compositor to forbid a third-party client from even working in the first place:
so even a compliant client would not necessarily be allowed to run across all compliant compositors. But I don’t mean that it’s impossible to write compliant clients, just that there’s more variability allowed on the compositor end than in a comparable X11 implementation. E.g. they may or may not recover a lost session, and the exact (secure) manner in which that’s done is compositor-specific, and may involve the compositor spawning a new client. This accomodates more variability than Xscreensaver’s currently design has to accommodate for X11.
On top of that, a program comparable to Xscreensaver would have to implement not only session-lock, which I think is only properly supported by wlroots? but also whatever Mutter and KWin use, and whatever other compositors will use in the future. Xscreensaver does have some hacks specific to e.g. both KDE and Gnome, mostly in the systemd shim in order to work around the quirks of the screensaver inhibit mechanism, but must of the code that achieves the actual locking is common to anything you may be running on the X side. There’s a lot of system-specific code of course (e.g. in unlocking methods) but that’s not related to the display server per se and would presumably have to be replicated by a comparable Wayland implementation (modulo things like pre-PAM Kerberos code which I think the British Museum should just call dibs on already).
I understand that’s a necessary trade-off, both because it needs to accomodate a wide range of compositor architectures and because it needs to fit in Wayland’s “frame perfection” idea. What scares me is that protocol-allowed timeouts are occasionally misused in practice – i.e. not that a sound, compliant implementation has a specific weakness, but the kind of bugs a bad implementation could have.
E.g. it sounds like one could race the locker for resources and prevent it from allocating the necessary resources and rendering the first frames, thus delaying the actual locking moment until the implementation-specified timeout. That’s one timing bug away from never (or hours), or one unreasonable value away from a long enough window to allow exploiting other bugs in the locker or the compositor, in the kind of code that I bet won’t see much testing on compositor implementations. (Note that I am, once again, thinking of an implementation comparable to Xscreensaver: some of its screensavers (“hacks”) are pretty ellaborate, they involve pretty heavy 3D graphics, one has a full 6502 emulator with CRT emulation shaders etc. – so they legit need a lot of resources).
I know it’s not something you have control over at the protocol end. Even assuming a bug like that occurs in a popular compositor, and it’s trivial to trigger, I still think you’re right when saying that
both compared to what compositors were doing before it and compared to X11. Hypothetical bugs in an implementation are exactly that, hypothetical, whereas current flaws in other locking protocols (and, God, X11) are very real. It’s just decades of exposure to (mostlly X11) Linux desktop code has conditioned me to think less in terms of “how does this help” and more in terms of “how will this be misused to work around application bugs”.
You’re quite right that this timeout mechanism for the purposes of frame perfection is the most complex part of the protocol and therefore the most likely cause of bugs and vulnerabilities in the compositor implementation. In the end, the user must trust their compositor implementation to have any expectation of security.
The most secure thing a compositor could do would be to forego frame perfection and immediately blank all monitors until the session lock client has rendered its first frames.
For what it’s worth, I opted for the more complex but frame-perfect option for my compositor, river. The implementation has thus far seen no bugs that allowed access to a session that should have been locked. There were however multiple assertion failures hit by users in the wild as I worked out all the edge cases inherent to asynchronous programming in the early days of the protocol implementation. It’s been a while (>6 months?) since I’ve had any report of a bug relating to river’s session-lock implementation.
Right, I suspect any exploitable behaviour there hinges on associated bugs (or poor timeout choices) in the compositor, not at the screen lock end. This situation is somewhat reversed compared to XScreensaver (where the display server and the WM don’t really get to do anything about the screen getting locked) but does have the distinct advantage that the compositor can (modulo bugs) do the right thing regardless of what the locker does. In X11 land, if xscreensaver crashes when the locker is initialised, or can’t grab focus or whatever, the session remains unlocked (or at least remained unlocked at some point, or on some configurations, I’m sure there some setup where you get that awful “Press Ctrl+Alt+F1 and restart the login session” message nowadays).
I’m going to pre-emptively apologize for spamming your inbox, I know I’ve already posted in this thread but that message is old enough that netiquette would demand I don’t edit it, and this one’s somewhat oblique to it. I’ve re-read the specs more closely (my interest in Wayland waned, uh, years before session-lock was proposed, so I’ve only learned about it by browsing Github a few months back) and I have a bunch of questions now :-D.
How does session-lock handle screensavers that want to apply desktop effects (e.g. like Cityscape?). I expect the screen locker program can’t just be granted arbitrary “screenshotting” privileges forever, and should only be allowed to grab an image of the desktop, or some arbitrary surface, when locking the screen. However, when the compositor delivers the lock message, it’s also supposed to blank all surfaces (except for some compositor-specific ones). Is there a way for all compliant clients to request that, or would that entail writing compositor-specific code?
If the client dies while it’s allocating resources, while the compositor is waiting for it to create and render session lock surface but before the locked message has been delivered, is it possible to distinguish between that and an input-triggered abort? I.e. can the compositor easily determine if the screen locker crashed while initializing and keep the session lock or an input event arrived just in time to trigger a lock abort? Or is this sequence atomic (i.e. once it’s started, locking is guaranteed to always succeed, unless the client crashes) so it’s a non-problem?
Is there any support for inhibiting the screen locker in session-lock (for a set period, or while a program is running etc.)? This is one of the things that XScreensaver really struggles with (as X11 makes no specific provisions for screen locking and the existing systemd-based mechanism is completely inadequate).
No worries!
This is not something currently handled by the session-lock protocol. It could be added to the protocol in a backwards compatible way by adding an event which provides the client with a screenshot of all monitors at the time which is sent by the compositor in response to the
ext_session_lock_manager_v1.lockrequest. This is not something I personally have a use-case for or interest in working on though.This is atomic, once the compositor receives the
ext_session_lock_manager_v1.lockrequest the session is locked even if the client crashes right after sending it. Sending thelockrequest does not require the client to allocate any significant resources or render any surfaces.This is out of scope of the session-lock protocol. There is however an idle-inhibit protocol that allows e.g. a video player to inform the compositor that idle should be inhibited while a video is playing. Compositors generally offer their own configuration options around when the session should be considered idle and allow disabling idle manually for a time frame. This kind of policy is something that’s intentionally not left up to clients on Wayland.
Hope that clears things up a bit!
It does! Thank you very much!
May be veering off-topic, but: it’s delightful to see this sort of pride in print.
“Impostor syndrome” is definitely a real thing, and it’s very helpful to those suffering from it that people talk about it these days. And many people who aren’t impostors, but are early on their particular learning curves, feel happier talking about that than they did years ago when I was a junior.
But it gives me an emotional lift to see someone who is an expert in a field recognise that fact and call it out when relevant :)
[Comment removed by author]