Against /Tmp

(dotat.at)

135 points | by todsacerdoti 5 hours ago ago

104 comments

  • 0xC0ncord 5 hours ago

    I'm amazed that polyinstantiation of directories via pam_namespace.so[1] is so unheard of. Setting this up fixes almost all of the qualms mentioned in the article by giving each user their own mount namespace with an isolated /tmp directory (and others if configured). Still though, this wouldn't prevent poorly written applications using /tmp from clashing with others that are running under the same user.

    It's relatively easy to set up[2] and provides a pretty huge defense mitigation against abusing /tmp.

    [1] https://www.man7.org/linux/man-pages/man8/pam_namespace.8.ht...

    [2] https://docs.redhat.com/en/documentation/red_hat_enterprise_...

    • cryptonector 9 minutes ago

      If you're not using PAM then you don't get these.

      For example, Kubernetes doesn't use PAM in the pods it creates to run your containers.

      You might think "who cares", but I've written code that is agnostic as to whether it's running in a logged-in user's session or something else. https://news.ycombinator.com/item?id=41916623

    • aidenn0 3 hours ago

      Is there an easy way to duplicate a specific process' namespace? My biggest issue with all these new features is that privatize state is how much harder it is to reproduce a state.

      Back when it was just environment variables, I could pipe /proc/PID/environ to xargs and get basically the same state. Given that things like unix domain sockets may end up in $TMPDIR, I can be left unable to do certain things.

      • xerxes901 3 hours ago

        /proc/PID/root is a view of that process’s mount namespace.

        Also you can use nsenter(8) to run a command (or even a shell) under another process’s mount, pid, network, etc namespace.

        • aidenn0 3 hours ago

          Thanks!

          It's exactly what I was looking for, and the world can now continue to improve without breaking any of my workflows :)

        • zokier 2 hours ago

          mount namespace and root directory are bit different things though.

          /proc/$PID/ns is the place to look for namespaces

      • zokier 3 hours ago

            nsenter --all --target $PID
        
        or something like that?

        https://man7.org/linux/man-pages/man1/nsenter.1.html

      • zbentley 3 hours ago

        I don't think there is, or should be, a way to do that. Granular copying of per-process resource state seems like a need that would be better served at either a closer-to-the-program layer (i.e. debug hooks in code you control that provide information on how to reconstruct its state) or much further away (e.g. via CRIU/whole-machine snapshots or scary tricks like SIGSTP or ptrace-injecting calls to fork(2)).

        > I can be left unable to do certain things

        Most of what I can imagine of "certain things" falls into two categories: debugging (for which much better tools exist), or concerns that would be better served by a program providing an API of some kind rather than "go muck with state in $TMPDIR".

        • aidenn0 3 hours ago

          Here's a recent one; I needed to play some sound via an ssh login session. A Wayland/pipewire session was already open. I was able to do this just by copying a running processes environment. With enough containerization &c. I'll need to do more things to do that, if it's at all possible.

          Also, /proc/ is (among other things) a debug interface.

    • yjftsjthsd-h 4 hours ago

      There's also https://www.freedesktop.org/software/systemd/man/latest/syst... to do the same for services if you use systemd.

    • fanf2 2 hours ago

      Lovely, another layer of complexity to increase the safety of a fundamental mistake that we can no longer fix!

  • scottlamb 3 hours ago

    > There should be per-user temporary directories. In fact, on modern systems there are per-user temporary directories!

    On Linux+systemd, I think this is referring to /run/user/$UID. $XDG_RUNTIME_DIR is set to this path in a session by default. There's a spec for that environment variable at <https://specifications.freedesktop.org/basedir-spec/latest/>. I assume there's also some systemd doc talking about this.

    On macOS, I see that $TMPDIR points to a path like /var/folders/jd/d94zfh8d1p3bv_q56wmlxn6w0000gq/T/ that appears to be per-user also.

    What do FreeBSD/OpenBSD/NetBSD do?

    • cryptonector 26 minutes ago

      Unfortunately /run/user/$UID/ is NOT universally available.

      On Linux it's typically created by a PAM, so if you're not using PAM then it doesn't exist. This means that on Kubernetes pods/containers... it doesn't exist!

      Yes, /tmp/ is a security nightmare on multi-user systems, but those are a rarity nowadays.

      Lots of things want to write things into /tmp, like Kerberos, but not only. I recently implemented a token file-based cache for JWT that... is a lot like a Kerberos ticket cache. I needed it because the tokens all have specific aud (audience) values. Now where to keep that cache?? The only reasonable place turned out to be /tmp/ precisely because /run/user/$UID/ is not universally available, not even on Linux.

  • cryptonector 23 minutes ago

    The right answer is to use /run/user/${UID}/. Unfortunately that's not universally available, not even on Linux. If you don't use PAM in the process of starting the user processes in question, then you won't have /run/user/${UID}/. That's because on Linux /run/user/${UID}/ is made by a PAM. Kubernetes does not use PAM, naturally, so you don't get this on Kubernetes.

    This is supremely annoying. /run/user/${UID}/ needs to exist universally. Ugh.

  • danans 15 minutes ago

    I get that /tmp as a shared world readable location is a security issue, but in a day of easy-to-provision VMs, serverless architectures, are there many true multiuser (not multi tenant) systems out there, in the sense of multiple users logging into the same logical system to complete compute tasks?

  • Joker_vD 5 hours ago

    > The fix, way back when, should have been for login(8) to create a per-user temporary directory in a sensible place before it drops privilege, and set $TMPDIR so the user’s shell and child processes can find it.

    Something like

        tmpdir := "/tmp/${USERNAME}"
        loop:
            rmdir(tmpdir, recurse=true)
            while not mkdir(tmpdir, 0o700, must-create=true)
        chown(tmpdir, user=$USERNAME, group=$USERGROUP)
        export("TMPDIR", tmpdir)
    
    with /tmp having root:root owner with 0o775 permissions on it? Yeah, would've been nice.
    • cryptonector 6 minutes ago

      /tmp is 01777

      Anything that requires login(8) or PAM to make it happen is insufficient. This has to happen in environments like Kubernetes too.

    • tgv 4 hours ago

      MacOS does something like this. Not by username, but through /private, which is a private mount, and then /tmp is linked to /private/tmp, as are /var and /etc.

      • js2 3 hours ago

        You're right that macOS has per-user temp (and cache) dirs under /private/var/folders/ (since 10.5), but it still has traditional shared /tmp (via the /private/tmp symlink) since not everything respects the per-user temp dir.

        https://magnusviri.com/what-is-var-folders.html

        That's not the reason for /private though. Rather, /private is a holdover from NeXTSTEP days which could mount the OS via NFS (NetBoot), and where /private was local to the machine:

        "Each NetBoot client will share the server's root file system, but there are several administrative files (such as the NetInfo database, log files, and the swapfile) that must be unique to each client. The server must have a separate directory tree for each client, which the client mounts on its own /private directory during startup. This lets a client keep its own files separate from those of other clients."

        https://www.nextcomputers.org/files/manuals/nsa/13_NetBoot.h...

        • lelandfe 3 hours ago

          Thanks for that first link, explained some stuff I've been curious about

    • nullindividual 5 hours ago

      Why not both, like Windows?

      $HOME/.tmp for user operations and /tmp for system operations?

      EDIT: I see from other posters it can be done. Why the heck isn't this the default?!

      • gspencley 4 hours ago

        IMO even a home-level, per-user tmp directory isn't ideal (though it is better). In a single-user environment, where malware is the biggest concern in current times, what difference does it make if it's a process running under a different user or one that is running under your current user that is attacking you?

        In other words, for many systems, a home-level temp directory is virtually the same as /tmp anyway since other than system daemons, all applications are being started as a single user anyway.

        And that might be a security regression. For servers you're spinning up most services at bootup and those should either be running fully sandboxed from each other (containerization) or at least as separate system users.

        But malware doesn't necessarily need root, or a daemon process user id to inflict harm if it's running as the human user's id and all temp files are in $HOME/.tmp.

        What you really want is transient application-specific disk storage that is isolated to the running process and protected, so that any malware that tries to attack another running application's temp files can't since they don't have permission even when both processes are running under the same user id.

        At that point malware requires privilege escalation to root first to be able to attack temp files. And again, if we're talking about a server, you're better off running your services in sandboxes when you can because then even root privilege escalation limits the blast radius.

        • nullindividual 3 hours ago

          > In a single-user environment, where malware is the biggest concern in current times, what difference does it make if it's a process running under a different user or one that is running under your current user that is attacking you?

          In these systems, the responsibility passes to EDRs or similar. But neither a $HOME/.tmp or /tmp matter in these scenarios. _Shared_ systems are where the concept of $HOME/.tmp might be more interesting.

        • pjc50 3 hours ago

          > In a single-user environment, where malware is the biggest concern in current times, what difference does it make if it's a process running under a different user or one that is running under your current user that is attacking you?

          Very true, and this is a real weakness of the UNIX (and Windows, even worse!) style security model in the modern environment. Android/iOS do a lot better.

          • marcosdumay 2 hours ago

            > Android/iOS do a lot better.

            They would if they were designed with the user's security in mind, instead of Google's/Apple's control.

            But I disagree, they don't do better at all. Any software that wants to get access to everything just needs to insist.

            • anthk 35 minutes ago

              Check pledge/unveil under OpenBSD. You get isolated software yet with freedoms.

              • marcosdumay 7 minutes ago

                I've recently packed some Linux software in flatpak. It's surprisingly good.

                Not as good as a real capability-based access control, but quite good compared to the other things that are usable on Linux.

      • ndsipa_pomu 2 hours ago

        I'm guessing, but I would think that the idea is to have all the junk in one place so that it can be safely cleared at startup and excluded from backups.

        If the user tmp files were placed in /tmp/${USER}/ then that would achieve the same goal.

      • yxhuvud 4 hours ago

        What system operations exist that need temp storage shouldn't have a separate user anyhow?

        • nullindividual 4 hours ago

          I see where you're going with your question, but like Windows' Services/scheduled tasks, most of those 'users' don't have a $HOME folder.

          Not to say they couldn't have one!

          • GoblinSlayer 3 hours ago

            Services on windows have home folder e.g. in \Windows\ServiceProfiles\LocalService

  • ricardo81 5 hours ago

    I guess the general gist is shared spaces between users causes security issues.

    I recall using 'shared hosting' where instead of using your default IP address for fetching anything from the network, you could do some funky stuff in the shared environment to discover many more IPs that could be used. Useful for scraping and such. Generally any shared hosting that used cpanel would expose all their network interfaces, often a /24 or two.

    • deltaburnt 5 hours ago

      Any shared resource seems to give rise to security issues. Extracting data through side channels in the hardware's architecture is what woke me up to this.

      • TeMPOraL 4 hours ago

        That's true of physical reality itself. Everything that happens constantly leaks information to the surrounding, spreading outward at the speed of light.

        Point being, there always are side channels.

      • stevekemp 2 hours ago

        I recently had to copy a secret which was available in a CI-job to a new repository, but the system was smart enough to filter it if echoed literally.

        So "echo $API_TOKEN" failed, but getting the output of the complete environment was as easy as "env | base64".

      • ricardo81 4 hours ago

        I remember digging into this 10-15 years ago. 'shared hosting' per provider had some arbitrary resource restrictions, but you could still find out via a cron job or some such. Like `cat`ting /etc/network stuff. Basically a sieve.

  • Aardwolf 5 hours ago

    I like /tmp in RAM myself, it's truly temporary that way

    EDIT: I do this more for avoiding certain disk reads/writes than security actually

    • cryptonector 5 minutes ago

      Ok, but that's not relevant or responsive to TFA.

    • tolciho an hour ago

      This is fine until something uses more memory than is available, such as sox insisting on routing a huge audio file though a too-small /tmp, or the MATLAB installer likewise only using /tmp. With sox you could in theory recompile to get it to use some other path (iirc none of the TMP or TMPDIR environment variables did anything), but I instead gave up on the /tmp in memory (it complicated the OpenBSD desktop setup). I forget exactly how I worked around the MATLAB installer issue, probably something horrible involving LD_PRELOAD or time wasted reconfiguring and rebooting and reconfiguring and rebooting one node to do the install on, plus more time wasted running the massive and bloated installer process(es) under strace to see exactly what file paths were in play.

      So, not really a fan of /tmp in memory. (And I don't much run massive and bloated browsers that may murder your SSD lifetime with excessive file writes better diverted to an in-memory /tmp.)

    • noirscape 5 hours ago

      It's also the default on most distros these days since it means /tmp is always wiped on every reboot. (For a programming side, this also means that if you write a file to /tmp, it'll probably have the fastest read/write speed you can find on the OS, which can be desirable.)

    • nullindividual 5 hours ago

      You'd need to pin pages in physical memory to guarantee it stays in physical memory. What happens if an 'attacker' (or accidental user) exceeds available physical memory? OOM Kill other applications? Just don't accept temp data, leading to failures in operations requested by the user or system?

      Pages in physical memory are not typically zero'ed out upon disuse. Yes, they're temporary... but only guaranteed temporary if you turn the system off and the DRAM cells bleed out their voltage.

      • noirscape 5 hours ago

        By default a tmpfs has a really low RAM priority so the OS will try to move it in swapspace if memory gets low. tmpfs size is specified on creation of the tmpfs (and cant be larger than the total memory available, which is swap + RAM) but it's only "occupied" when files begin to fill the tmpfs.

        If it gets too full for regular OS operations, you get the fun of the OOM Killer shutting down services (tmpfs is never targeted by the OOM Killer) until the entire OS just deadlocks if you somehow manage to fill the tmpfs up entirely.

        • nullindividual 5 hours ago

          > OS will try to move it in swapspace if memory gets low

          That defeats the idea GP presented.

          • dspillett 4 hours ago

            Only if memory gets low, otherwise it'll stay in RAM and give the benefit GGP intended. IIRC tmpfs data shouldn't be evicted to swap just to allow more room for cache, or if an app requests a large chunk of memory but doesn't use it, just to allow more room for application pages that are actively in use.

            Normal case: tmpfs data stays in RAM

            Worst case: it is pushed to swap partitions/files, which is no worse than it being in a filesystem on physical media to start with (depending on access patters and how swap space is arranged it may still be a little more efficient).

            It isn't quite the same as /tmp being on disk anyway but under normal loads in cache, because the data will usually get written to disk even if only ever read from cache and the cached data from disk will be evicted to make room for caching other data where tmpfs data is less likely to.

          • noirscape 5 hours ago

            That depends on how you view swapspace; on most devices, swapspace is either created as a separate partition on the disk or as a file living somewhere on the filesystem.

            For practical reasons, swapspace isn't really the same thing as keeping it in an actual storage folder - the OS treats swapspace as essentially being empty data on each reboot. (You'd probably be able to extract data from swapspace with disk recovery tools though.)

            On a literal level it's not the same as "keep it in RAM", but practically speaking swapspace is treated as a seamless (but slower) extension of installed RAM.

            • nullindividual 4 hours ago

              > On a literal level it's not the same as "keep it in RAM"

              I read the GP as 'literal level' in-RAM. If I interpreted that incorrectly, apologies to GP.

              • marcosdumay 2 hours ago

                It may or may not be what the OP was talking about, depending on your threat model.

      • RiverCrochet 2 hours ago

        Well I guess you could tell Linux to not use some memory addresses using the BadRAM feature, then setup an `mtd` device to those memory addresses and create a RAM-based block device, then use `cryptsetup` to encrypt it. If your Linux box is headless and you have a GPU with RAM there mostly sitting unused then you could use the VRAM.

      • Aardwolf 5 hours ago

        I use this with a size of a few GB: https://wiki.archlinux.org/title/Tmpfs

    • pama 5 hours ago

      The /tmp in RAM does not address any of the vulnerabilities unfortunately.

      • Aardwolf 5 hours ago

        At least the 'tmp cleanup' related ones from the article

        • pama 5 hours ago

          No not really. These are there for long running jobs. Reboot clean up of tmp is not an issue.

    • rnd0 4 hours ago

      I thought that was the standard in Linux, at least. I'm not sure how they do it in the BSDs.

  • TeMPOraL 4 hours ago

    In which people forget that computers have other purposes beyond being boxes for CTF competitions. Shared mutable global state isn't always bad.

    • pjc50 3 hours ago

      If your machine is on the Internet in any way, you're taking part in the big ongoing global CTF.

    • inetknght 4 hours ago

      > Shared mutable global state isn't always bad.

      I agree, but I think that shared mutable global state is a bad default. I think it'd be better to be opt-in (eg, you get a `/tmp/${USER}` and your user can `chmod o+rw` during setup if it needs to be globally mutable.

    • samatman 37 minutes ago

      There are very few always in such matters, but I view this one as an 'except for rare circumstances'. Even when true, it should be modeled as "contained state where the container includes everyone".

      The problem is that Unices use access control, rather than capabilities, so ensuring state is shared only by those who need it is quite a bit more difficult than just punting, and declaring that 'those who need it' is 'everyone'.

      Nor has the design problem of a user-friendly capabilities architecture truly been solved, IHMO. Nonetheless, we shouldn't confuse convenience with correctness.

  • gnramires 2 hours ago

    I really think there are quite a few reforms and new ideas that could help Unixes. Also it's not only about introducing features/new ways, but also the right culture and instruction around the new ways.

    For example, the Android(/iOS?) permission based model at kernel level where apps (that could be processes in general?) can only access some private storage (which presumably has its own isolated tmp/ directory) really should be default, and permissions should be opt-in (of course, there should be a 'legacy permission' that makes things work as before).

    (I believe most of permission functionality is technically possible through SELinux (??), or you could use containers, but is not easy to use or default)

    I think containers arose partially to provide some of this isolation? But they have their own overhead and redundancy issues.

    ---

    It seems some of this work is being done in SELinux project? Is it going to be enough? (and easy enough to use by default?)

    https://wiki.archlinux.org/title/SELinux

    I think a simple permission model might have been more elegant than the SELinux model ?

    • anthk 34 minutes ago

      Pledge/unveil it's intristic, per software, under OpenBSD.

  • stabbles 3 hours ago

    To hide `/tmp` from other processes and users, I sometimes use `bwrap --dev-bind / / --tmpfs /tmp <command>`.

    Unfortunately Ubuntu 24.04 has put restrictions on unprivileged user namespaces, so that it no longer works out of the box :(

  • Aissen 5 hours ago

    That does not expand on the whole TOCTOU-style family of bugs, which permeates all APIs, and the only solution is to manipulate everything by file descriptor; Linux has many syscalls for that: openat, mkdirat, renameat(2), unlinkat, execveat, (new)fstatat, symlinkat, faccessat, fchmodat, fchownat, linkat, mknodat, pidfd_*, etc.

    Arguably, many are not relevant to /tmp, but it's good to keep in mind.

  • udev4096 5 hours ago

    The only thing I know about /tmp is that it's accessible by all users, privileged or not, which is quite helpful when you are escalating your user privilege on a box

  • tmountain 5 hours ago

    Things goes along with the author's "tmp cleanup" section, but I have lost valuable work on a number of occasions from hacking on random files that I created in /tmp under the assumption that they were throwaway junk files, only to reboot my machine a few hours later and have them automatically deleted by the OS. It's much safer and just as easy to use a "$HOME/tmp" dir as a junk drawer and then manually clean it up from time to time.

    • zimpenfish 5 hours ago

      Pro* tip: don't put your mSQL database file on /tmp on a Solaris box.

      Because at some point a few months later people will say "where did the database go?" and you'll have a lot of explaining and reconstruction to do.

      (mid 90s)

      • hulitu 4 hours ago

        I think this one was in the "Unix admin horror stories"

        • stevekemp 2 hours ago

          Like those users who start with Linux, and later move to Solaris only to learn "killall" does something different there..

          In my defense I only did it the once.

        • zimpenfish 3 hours ago

          Wish I'd read that before I did it then.

    • Joker_vD 5 hours ago

      > valuable work

      > created ... under the assumption that they were throwaway junk files

      Don't leave your valuables in the office trash bins (they get cleaned every 3 hours), what else can I say?

    • ziml77 3 hours ago

      It's best to assume that any directory which holds temporary files for applications will be cleaned up at any time. The whole point of those directories is to hold things that need to exist somewhere but are ephemeral.

    • akdev1l 5 hours ago

      You can use /var/tmp for this purpose

      It is not cleared between reboots

      • NekkoDroid 3 hours ago

        Do note that systemd does have a tmpfiles.d (terrible name nowadays, but that is besides the point) drop-in with an extra service that will clean out /var/tmp/ of unused files when they haven't been accessed within 30 days (all of a/m/ctime are checked). Same applies to /tmp/ but with 10 days. I don't know if the service is enable by default on any distros though, so assume it is unless otherwise ensured :)

      • SoftTalker 4 hours ago

        Depends on the OS. In OpenBSD, /var/tmp is a symlink to ../tmp and is so is cleaned on reboots and periodically.

  • aidenn0 3 hours ago

    > It’s a bad idea because it’s shared global mutable state that crosses security boundaries.

    I think there is a use for such a thing (I take advantage of these features somewhat regularly), but having it also be the default $TMPDIR is definitely a bad idea.

    • zbentley 3 hours ago

      I think this is an instance where, to crib a phrase from the golang world, "share memory by communicating" (i.e. programs that need to support this kind of intervention should provide some form of API) is more appropriate than "communicate by sharing memory" (mucking about with programs' runtime state in tmpfs).

      I replied to your similar comment upthread as well.

      • aidenn0 3 hours ago

        Once shells have easy-to-use support for sending and receiving data between two sessions running as two users, then maybe we can get rid of shared filesystem directories.

        I think /tmp is a poor solution even if we are going to use the filesystem for this (some sort of per-user spool makes far more sense), but its value is in its ubiquity.

  • pjmlp 5 hours ago

    So here we have again how "Worse is better" works in practice, and how we got here regarding /tmp in 2024.

    • anthk 4 hours ago

      As if C:\TEMP or %tmpdir% were any better.

      Or using letters as drivers.

      Worse is better? A lot of tech in Win32 is built as if it were for DOS 1.0 or CP/M. See AUX, PRN, COM and so.

      • pjc50 3 hours ago

        Backward compatibility, innit.

        Microsoft have tried to get people to use the newer, more heavily sandboxed APIs like UWP, but only very weakly, and they haven't committed to transitioning their own apps over as dogfood. Nearest they've got is actually migrating a lot of office to the cloud as Office365.

        Sunsetting Win32, or even having significant backwards-compatibility breaks, would upset so many corporate customers who would then refuse to upgrade.

      • pjmlp 2 hours ago

        Yeah, nice jab attempt, except no one sells MS-DOS decisions as some grandiose OS architecture design.

        Its origins are quite clear, QDOS, Quick and Dirty Operating System.

        https://en.m.wikipedia.org/wiki/86-DOS

      • tredre3 3 hours ago

        > As if C:\TEMP or %tmpdir% were any better.

        I mean, yes? %tmp% is in the user's directory, not accessible by the world.

        • anthk 38 minutes ago

          TMPDIR can be trivially set at $HOME/tmp too with just a file at /etc/profile

  • jmclnx 5 hours ago

    What I do is all users get TMPDIR set to /tmp/$USER and /etc/rc.d/rc.local will create these as 700 on boot. Plus a script in /etc/profile.d/ will set TMPDIR on login for the users. With this you get /tmp cleanup on boot.

    As as someone said, you can mount /tmp as tmpfs if you can spare the memory.

    • stevekemp 2 hours ago

      Back in the day I used libpam-tmpdir for that purpose - it covered SSH and other services that used PAM.

  • CarpaDorada 5 hours ago

    Is it possible to configure every user to see /tmp as $USER/.tmp via some Linux isolation method (namespaces)?

    • 0xC0ncord 5 hours ago

      This exact thing is possible with pam_namespace.so!

      • CarpaDorada 5 hours ago

        Very nice, thank you. I will look into this. This may be my break into PAM that I've ignored thus far.

        I'm wondering if there's programs that will break with such a change. One example would be if multiple users in a group need access to the same file under /tmp.

        • 0xC0ncord 4 hours ago

          pam_namespace normally isolates /tmp by user or SELinux context, so your example might require a couple tweaks. I haven't tried any of these but I'm thinking any of:

          1) You could modify the namespace init script used by pam_namespace to also mount a shared directory under each user's /tmp, and do this only for the users who need it.

          2) Rely on a different shared directory for the users who need it.

          3) Configure namespace.conf to isolate by SELinux context and put each user who needs a shared /tmp into the same SELinux role.

          • CarpaDorada 4 hours ago

            What occurs to me now is that with a proper SELinux configuration you do not even need per-user /tmp, you can use the old /tmp for all. It is still motivating to look into PAM, but perhaps also motivating to learn more about SELinux that I've also put off.

    • notamy 5 hours ago

      For a janky way of doing it, create a new mount namespace, then bind-mount $HOME/.tmp over /tmp. In practice better ways (ex. sibling comment) exist and you should use those.

  • fforflo 2 hours ago

    Whenever I find myself needing /tmp, it's usually as a form of IPC shared memory, in which case I use /dev/shm directly.

  • josephcsible 3 hours ago

    If you're opening with O_CREAT|O_EXCL, why does it matter whether the filename is predictable?

    • fanf2 3 hours ago

      Denial of service, the next point in that list.

    • kijin 3 hours ago

      Because other processes can periodically check whether a predictable filename is in use, and guess things you'd rather keep private?

      • johnisgood 3 hours ago

        Why would you have processes you do not trust, or why not use firejail for those that may pose a security risk?

        > Firejail is a SUID sandbox program that reduces the risk of security breaches by restricting the running environment of untrusted applications using Linux namespaces, seccomp-bpf and Linux capabilities. It allows a process and all its descendants to have their own private view of the globally shared kernel resources, such as the network stack, process table, mount table. Firejail can work in a SELinux or AppArmor environment, and it is integrated with Linux Control Groups.

        It supports "--private" (mounts new /root and /home/user directories in temporary filesystems), along with "--private-{bin,cache,cwd,dev,etc,home,lib,opt,srv,tmp} (plus "noexec /tmp")". It also supports "keep-config-pulse", "keep-dev-shm", and so forth, meaning you can have shared files between process if you so wish (for DBus, etc.).

      • josephcsible an hour ago

        But you wouldn't need to guess names to do that, since the names of files in /tmp are publicly listable.

  • Starlevel004 2 hours ago

    The actual answer is to use O_TMPFILE.

  • layer8 5 hours ago

    > Probably the main reason was path-dependence

    Nice pun. :)

  • irunmyownemail 4 hours ago

    I use a tmp dir in my home folder on my machines too, I like the idea of tmp.

  • jauntywundrkind 5 hours ago

    Oh man, this sort of thing is part of what I love love love about systemd. It bakes in so many great isolation/sandboxing/privacy measures for units! From the article:

    > There should be per-user temporary directories. In fact, on modern systems there are per-user temporary directories! But this solution came several decades too late.

    > If you have per-user $TMPDIR then temporary filenames can safely be created using the simple mechanisms described in the mktemp(1) rationale or used by the old deprecated C functions. There’s no need to defend against an attacker who doesn’t have sufficient access to mount an attack! There’s no need for sticky directories because there aren’t any world-writable directories.

    May I introduce you to PrivateTMP= ?

    > PrivateTmp=¶

    > Takes a boolean argument. If true, sets up a new file system namespace for the executed processes and mounts private /tmp/ and /var/tmp/ directories inside it that are not shared by processes outside of the namespace

    https://www.freedesktop.org/software/systemd/man/latest/syst...

    Notably you don't even need to change how programs work (no $TMPDIR necessary)! It creates a filesystem namespace for your process, such-that you see the normal fs, but with your own /tmp ! That way your program behaves regularly/as convention goes everywhere else, and existing programs you run can also benefit without re-writing!

    I cannot emphasize enough how many excellent well integrated kick ass security features systemd gives you totally for free. DynamicUser= turns on PrivateTmp= by default and is an easy way to insure isolation, to prevent needing to hand-code & safely manage uid/gids yourself; I'd start there if you can.

    There's so so so many great isolation features in this man page.

    • bloopernova 4 hours ago

      That is very cool, thank you for sharing it.

      I wonder if Fedora does this by default?

    • GoblinSlayer 3 hours ago

      Happy debugging, yeah. FastCGI examples usually create sockets in /tmp, but nginx doesn't see them, go figure.

  • hulitu 5 hours ago

    > Against /Tmp

    This is like a pope talking about celibacy.

    Did he try to remove /tmp entirely and see how it goes ?

    • yjftsjthsd-h 3 hours ago

      That makes little sense; the author's complaint amounts to "programs should not use /tmp", so removing it before fixing all programs would be putting the cart before the horse.