Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

session-management.md: Proper handling of XDG_RUNTIME_DIR #635

Closed
camoz opened this issue Dec 24, 2021 · 9 comments · May be fixed by #792
Closed

session-management.md: Proper handling of XDG_RUNTIME_DIR #635

camoz opened this issue Dec 24, 2021 · 9 comments · May be fixed by #792

Comments

@camoz
Copy link
Contributor

camoz commented Dec 24, 2021

The docs have a section called XDG_RUNTIME_DIR which advises users that are not in a elogind environment (which takes care of XDG_RUNTIME_DIR automatically) to manually manage it through the shell:

Alternatively, manually set the environment variable through the shell. Make sure to create a dedicated user directory and set its permissions to 700. A good default location is /run/user/$(id -u).

This is not trivial to do while staying compliant to the XDG spec. Here's the relevant part:

$XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential runtime files and other file objects (such as sockets, named pipes, ...) should be stored. The directory MUST be owned by the user, and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700.

The lifetime of the directory MUST be bound to the user being logged in. It MUST be created when the user first logs in and if the user fully logs out the directory MUST be removed. If the user logs in more than once he should get pointed to the same directory, and it is mandatory that the directory continues to exist from his first login to his last logout on the system, and not removed in between. Files in the directory MUST not survive reboot or a full logout/login cycle.

The directory MUST be on a local file system and not shared with any other system. The directory MUST by fully-featured by the standards of the operating system. More specifically, on Unix-like operating systems AF_UNIX sockets, symbolic links, hard links, proper permissions, file locking, sparse files, memory mapping, file change notifications, a reliable hard link count must be supported, and no restrictions on the file name character set should be imposed. Files in this directory MAY be subjected to periodic clean-up. To ensure that your files are not removed, they should have their access time timestamp modified at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.

If $XDG_RUNTIME_DIR is not set applications should fall back to a replacement directory with similar capabilities and print a warning message. Applications should use this directory for communication and synchronization purposes and should not place larger files in it, since it might reside in runtime memory and cannot necessarily be swapped out to disk.

On IRC it was recently proposed to instead manage XDG_RUNTIME_DIR via pam_rundir in environments without elogind.

It seems there is also another alternative already packaged: rundird

@Duncaen
Copy link
Member

Duncaen commented Dec 24, 2021

The lifetime requirement is pretty pointless, if programs fail to handle unclean $XDG_RUNTIME_DIR directories they are buggy, logging out of your desktop environment does not mean all sessions, i.e. ssh will be closed which in turn means the directory is not cleaned.

@adigitoleo
Copy link

Note that the rundir repo is archived/unmaintained, and the original author has created an alternative that doesn't remove the directory.

At the moment I have a permanent 0700 dir in .config for each user, and

> cat /etc/profile.d/xdg_runtime_dir.sh
test -d $HOME/.config/$(id -u) && export XDG_RUNTIME_DIR=$HOME/.config/$(id -u)

Which is sort of similar to what the docs suggest, however I had issues with waypipe (ssh -X for wayland):

S10500: 62.445892 [src/server.c:504] Env. var XDG_RUNTIME_DIR not available, cannot place display socket for WAYLAND_DISPLAY="wayland-40PzNuz1sB"

This happens because ssh sessions aren't login sessions, and don't source remote profile scripts by default. Eventually, I solved the issue by putting the same line in ~/.zshenv for each user.

Maybe dumb_runtime_dir or pam_rundir provide a more general way of doing it, I don't quite understand PAM yet though. If they work, I think it could be worth adding mentions to the docs. My other suggestion is to add a warning about the fact that setting XDG_RUNTIME_DIR needs to be done for any session, not just "login sessions", so that it is also set when logging in with ssh.

@nonchip
Copy link

nonchip commented Dec 29, 2021

@adigitoleo putting the runtime dir into $HOME sounds interesting, though not sure why you then also name it by the user. (also, like Duncaen said below, it only works if programs actually follow spec)

that said, the approach using a global dir has the definitive benefit of being in a ramdisk (something usually a normal user can't just mount), thus providing faster access without drive wear, especially since it's pretty much only used for stuff like pid files, sockets, fifos and mmap and doesn't really require any significant space.

also note the specific requirement:

It MUST be created when the user first logs in and if the user fully logs out the directory MUST be removed.
[…]
Files in the directory MUST not survive reboot or a full logout/login cycle.

so essentially you'd have to destroy and remake that directory whenever all "sessions" (however that's defined on your system) of a user quit, something that a simple shell script can't really provide reliably.

PAM / elogind and similar systems however can keep track of this.

My other suggestion is to add a warning about the fact that setting XDG_RUNTIME_DIR needs to be done for any session, not just "login sessions", so that it is also set when logging in with ssh.

but ssh is a login session. and handled by PAM/elogind just fine.

@Duncaen
Copy link
Member

Duncaen commented Dec 29, 2021

Deviating from /run/user/$UID/ comes with problems when programs don't actually follow the standard, as example chromium will not use XDG_RUNTIME_DIR and hardcodes /run/user/$UID/ when it setups the sandbox, resulting in permission issues.

@adigitoleo
Copy link

I see, thanks for the clarifications. I looked into pam_rundir but it seems there are some unresolved issues around the directory permissions. In this issue an artix guy mentions a fork of the project that apparently solves the issue. Void is not yet packaging that version.

Simple installation of the current pam_rundir package doesn't seem to work. I suppose I need to set up the pam module somehow?

My reservation about elogind does not come from an anti-systemd stance (although lack of systemd is probably an attractive feature of void for many users), but if all I want is to set up a directory and one environment variable, ~200k LOC seems rather overkill, so I'd prefer a simpler package for this.

As I understand, elogind also provides other features, but I don't seem to miss them. If they are really critical, I'd be happy to reconsider using it.

I tried to read through the Arch wiki on PAM but it's still a bit arcane to me. Setting up environment variables seems to be the easy part, but creating/destroying /run/user/$UID at the right time with the right permissions looks to be tricky.

For the simplest possible solution, would it be reasonable to simply create the directory once, never destroy it (flaunting the spec) and use pam_env to set up the variable?

@camoz
Copy link
Contributor Author

camoz commented Dec 30, 2021

@adigitoleo I think, unfortunately, pam_env should not be used to set this variable, since PAM deprecated reading of user environment variables:

Noteworthy changes in Linux-PAM 1.5.0

pam_env: Reading of the user environment is deprecated and will be removed
at some point in the future.

https://github.com/linux-pam/linux-pam/releases

There don't seem to be any good alternatives yet: https://www.reddit.com/r/archlinux/comments/l0ascx/pam_env_is_being_deprecated_any_alternatives/

Maybe we just need to wait a bit longer, to see which of the different "PAM rundir" implementations are stable and maintained in the future.

Right now there is:

  • rundird, in void repos, but was deprecated 3 days ago
  • dumb_runtime_dir, same author as rundird, will be packaged soon, but is only 5 days old. Not completely spec-compliant (doesn't destroy the rundir). From #voidlinux (with permission):
       mx08 | My issues are (were?): not packaged, very new, not completely spec-compliant                                    
       mx08 | All together that leaves me a bit unsure                                                                        
       mx08 | (Not for personal usage, but officially recommending it in the docs)                                            
       mx08 | E.g., what if it will be deprecated in a few months and there is a replacement in rust or so? ;)                
    ifreund | mx08: I wrote it in C this time because I don't want to ever touch the code or think about XDG_RUNTIME_DIR again
    ifreund | also it's less than 50 lines of code, if you're worried about quality read it yourself                          
    ifreund | anyhow, I plan to "maintain" it with the current feature set indefinitely                                       
    ifreund | "maintain" in quotes because I don't expect to ever need to change anything :P                                  
    
    Still it's not spec-compliant, so I'm not sure if it's good to officially recommend it in the docs.
  • pam_rundir in void repos, currently issues on void, created 6 years ago, author does not seem to be very active, no Github release tags, no answers to PRs etc.
  • the artix guy's fork of pam_rundir, not packaged in void, seems to work on void, 3 months old

@adigitoleo
Copy link

Makes sense. I'll probably wait for the dumb_runtime_dir package myself, but I can understand not recommending it. Was lurking IRC today so I've seen that discussion ;)

@Duncaen
Copy link
Member

Duncaen commented Dec 30, 2021

Another alternative, my favorite is just to create the directories in rc.local and export the variable from profiles.

bermudi added a commit to bermudi/void-docs that referenced this issue Feb 23, 2024
Manually setting `$XDG_RUNTIME_DIR` is not trivial to do while staying compliant to the XDG spec as noted in issue void-linux#635. This proposed way handles `$XDG_RUNTIME_DIR` properly without having to install `elogind` and should suggested as its alternative
@ahesford
Copy link
Member

Closing because the alternatives to manage the lifetime of runtime directories all have issues, the lifetime requirement on runtime directories has not been demonstrated to have any appreciable merit, and this issue has not seen continued activity.

@ahesford ahesford closed this as not planned Won't fix, can't repro, duplicate, stale Mar 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants