XDG_SESSION_TMPDIR

Ryan Lortie desrt at desrt.ca
Fri Apr 23 14:19:00 PDT 2010


Hi,

I'd like to propose a new freedesktop spec that creates an environment
variable for a secure session-scoped temporary directory.

The main use case here is to allow a directory through which to
synchronise intra-session IPC that for one reason or another doesn't use
DBus.  A few examples:

  - dconf will store a journal file here of outstanding changes not yet
    written to the database stored in the user's home directory

  - gvfs metadata storage wants to do the same

  - give a well-known location for unix sockets for session-scoped
    services

It's conceivable that even the session D-Bus would want to create its
socket in this directory.

--

The spec is simple.  Essentially, a XDG_SESSION_TMPDIR is introduced.

--

For application authors:

All processes belonging to the same session share the XDG_SESSION_TMPDIR
environment variable (set or unset).  Specifically, any processes
activated by the session D-Bus must have this variable set or unset
accordingly.

If XDG_SESSION_TMPDIR is unset, applications must behave by falling back
to an alternative mode of operation (which may be slower).

Assuming XDG_SESSION_TMPDIR is set, it refers to a directory of mode
0700 that is owned by the current user.  This directory was empty at the
start of the session (ignoring any files used by the implementation) and
the same directory is never used by more than one session at one time.

Applications should follow reasonable namespacing in order to avoid
stomping on other users of the directory.  Specifically, applications
should prefix any created file or subdirectory with their own name (ie:
dconf will name all files here with names starting with "dconf").

The value of the environment variable is always an absolute pathname.
It does not end with a slash.  No portion of the path is a symbolic
link.  The path name is canonical; it does not contain two sequential
slashes or have "." or ".." as any component.  Each component of the
path contains only alphanumeric characters plus underscore ('_'), dash
('-'), dot ('.') and colon (':'); in essence, the variable is
shell-safe.

The directory is always on a native local (read: not NFS or FUSE)
filesystem.  The directory may be on a memory-backed (read: tmpfs)
filesystem so it is essential that the directory not be used for storage
of large amounts of data.

--

Implementation notes:

Creating the directory on a memory-backed filesystem is preferred simply
because it's faster.

If no local filesystems suitable for session temporary directories exist
then the implementation must deal with this by not setting the
XDG_SESSION_TMPDIR environment variable.  It is absolutely forbidden to
set XDG_SESSION_TMPDIR to a location on an NFS or FUSE filesystem (or
similar).

The implementation can use whatever method it desires to ensure that a
directory is only used by one session and to clean up directories after
sessions exit.

One possible method is to have a small program that runs as part of the
session.  This program creates a session directory at a predictable
location and opens a ".lock" file within that directory.  If it can
acquire a write lock on this file then it ensures that the directory is
empty (ie: "rm *") and uses the directory as the XDG_SESSION_TMPDIR.
If any of this fails, the program attempts to use less predictable
names.  If all attempts fail, the program doesn't set the environment
variable.  The program then forks and launches the rest of the session,
watching for SIGCHLD and cleaning up the directory when the session
exits.

Periodically a cleanup process can run to check that there are no stale
session directories (ie: by trying to acquire the lock on them and
deleting them if they are unlocked).

A much simpler implementation may just be a shell script that uses
"mktemp -d" and a periodic cleanup script.

--

I'm attaching a quick hacked up proof of concept for the first mentioned
possible implementation.  I *think* that it won't delete your entire
home directory, but I refuse to be held responsible if it does. :)

The code probably looks weird because I tried to optimise it for using
as little memory as possible (since I feel a little bit guilty about
adding yet another process to everyone's session).  It turns out that my
efforts were probably a little bit wasted due to the vast amounts of
memory libc uses just by starting up.  In any case, it ends up using 86k
of writable memory when I run it on my system.

I used /dev/shm since that's a world-writable tmpfs that's available on
most Linux boxes these days.  I don't know if that's a good idea, but it
works.

In order to use this, just create a file in /etc/X11/Xsession.d *after*
where D-Bus gets launched (ie: higher number) containing:

  STARTUP="/path/to/xdg-session-tmpdir $STARTUP"

Pending discussion/flaming, I'll write this spec up properly and create
a git repository for a simple implementation (which may or may not look
like the one I've attached here) and start doing releases.  After that
it should be fairly trivial to vendors to start providing this.

One topic for discussion that I can see popping up is if we should have
per-user temporary directories in addition to session-scoped ones.  I
personally think that this is a little bit bogus.  Every now and then
the "per-user D-Bus" discussion pops up and the consensus there seems to
be that having more than one logged-in session of a given user is a bit
of a fringe case and can be handled just fine in the same way that we
handle multiple logins (on different machines) sharing an NFS home
directory.

Cheers
-------------- next part --------------
A non-text attachment was scrubbed...
Name: xdg-session-tmpdir.c
Type: text/x-csrc
Size: 5568 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/xdg/attachments/20100423/f29470b4/attachment.c>


More information about the xdg mailing list