NHacker Next
  • new
  • past
  • show
  • ask
  • show
  • jobs
  • submit
Against /tmp (dotat.at)
0xC0ncord 8 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 4 hours 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 7 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.

zokier 6 hours ago [-]

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

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

xerxes901 6 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.

zokier 6 hours ago [-]
mount namespace and root directory are bit different things though.

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

aidenn0 6 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 :)

zbentley 7 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 6 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 7 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 6 hours ago [-]
Lovely, another layer of complexity to increase the safety of a fundamental mistake that we can no longer fix!
scottlamb 6 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?

assimpleaspossi 14 minutes ago [-]
FreeBSD doesn't create user tmp when setting up a new user using the automatic tool. I don't recall if that's an option or not. There is, of course, a /tmp
cryptonector 4 hours 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.

anyfoo 27 minutes ago [-]
> Yes, /tmp/ is a security nightmare on multi-user systems, but those are a rarity nowadays.

What's not a rarity though is apps (or code in general) that you don't fully trust, and that you don't want to give a chance to exfiltrate all your data for example.

Sadly, the POSIX permission model is entirely ill-suited for that, precisely because it tries to solve the multi-user problem, wherein all code belonging to a single user is effectively treated omnipotent within that user's domain (i.e. the files the user owns). That's why iOS and macOS (the non-POSIX parts) has a container model with strong sandboxing, entitlements, etc.

zokier 1 hours ago [-]
Does k8s guarantee that /tmp is available either?
anyfoo 23 minutes ago [-]
iOS and macOS go further and separate their (native) apps almost entirely, including temporary files. That way, if you download "Super Free VPN Pro!!", it at least doesn't get access to, say, photos, temporary data or not.
cedws 4 hours ago [-]
I think the idea of a shared filesystem in general is bad. It’s not the 80s anymore where we’re logging on to a shared mainframe. Applications should be completely sandboxed from each other by default and only allowed to see what they need to see. Real sandboxing by default (not like systemd’s opt in sandboxing, which is an absolute mess) would eliminate entire classes of vulnerabilities.
anyfoo 21 minutes ago [-]
This has been iOS's (and macOS's, for native apps) model for a long time, yeah. "Multiuser" computers are not common anymore, but computers with a bunch of apps/code that you put different levels of trust in (especially on a level on what you want a given app to have access to), now are.

It's very different from 20-30 years ago.

Joker_vD 8 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.
tgv 8 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 7 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 6 hours ago [-]
Thanks for that first link, explained some stuff I've been curious about
nullindividual 8 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 7 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 7 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 7 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 6 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 4 hours ago [-]
Check pledge/unveil under OpenBSD. You get isolated software yet with freedoms.
marcosdumay 4 hours 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 6 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 8 hours ago [-]
What system operations exist that need temp storage shouldn't have a separate user anyhow?
nullindividual 8 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 7 hours ago [-]
Services on windows have home folder e.g. in \Windows\ServiceProfiles\LocalService
cryptonector 4 hours 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.

Joker_vD 49 minutes ago [-]
It doesn't have to be, does it? Drop the S_IWOTH from it.
Aardwolf 9 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

noirscape 8 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.)
rurban 2 hours ago [-]
I prefer the explicit /dev/shm for this.
tolciho 5 hours 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.)

anyfoo 16 minutes ago [-]
Ideally you have swap, so that stuff that's not actually in use ends up in swap instead of occupying physical memory.

That's why you still usually see machines with unreasonable amounts of GB of RAM having swap partitions: Instead of having data that's rarely, if ever, used occupy precious DRAM, it's much better to have that data in swap so that the DRAM can contain, say, filesystem caches.

nullindividual 8 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 8 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 8 hours ago [-]
> OS will try to move it in swapspace if memory gets low

That defeats the idea GP presented.

dspillett 8 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.

anyfoo 10 minutes ago [-]
True overall, but I think it makes a lot of sense to evict rarely used data in tmpfs to swap, so that the DRAM it occupied can be used for valuable caches instead of holding some obscure temporary data that will be rarely or ever accessed.

Rarely used data that got evicted then behaves more or less like a normal /tmp filesystem when it does eventually get accessed, i.e. it gets read in from disk, while other data still gets all the benefits from tmpfs (e.g. ephemerality).

(If you take the thought experiment to its logical conclusion, you'll anyway end up in transparent hierarchical storage a la AS/400, where all data is just addressed by a single pointer in a very very large address space and the OS decides where that currently points to, but let's stay within the confines of what we're mostly used to...)

cowsandmilk 3 hours ago [-]
Use of /tmp on regular file system has almost the same behavior because the kernel has a file system cache… if you’re using the file, it will remain available in RAM. There’s some subtle differences, but I’ve seen enough benchmarks around this to have realized that tmpfs doesn’t really have an impact.
anyfoo 46 seconds ago [-]
Yeah, that's why I think the prime feature of tmpfs is more ephemerality than anything else.
noirscape 8 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 8 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 6 hours ago [-]
It may or may not be what the OP was talking about, depending on your threat model.
akira2501 1 hours ago [-]
> exceeds available physical memory?

shm and memory mounts use half the available system memory by default. so this is not typically possible.

> are not typically zero'ed out upon disuse

They're zeroed when they're reallocated.

> and the DRAM cells bleed out their voltage.

This occurs in less than a second in almost every room temperature environment.

RiverCrochet 5 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 8 hours ago [-]
I use this with a size of a few GB: https://wiki.archlinux.org/title/Tmpfs
pama 8 hours ago [-]
The /tmp in RAM does not address any of the vulnerabilities unfortunately.
Aardwolf 8 hours ago [-]
At least the 'tmp cleanup' related ones from the article
pama 8 hours ago [-]
No not really. These are there for long running jobs. Reboot clean up of tmp is not an issue.
cryptonector 4 hours ago [-]
Ok, but that's not relevant or responsive to TFA.
rnd0 7 hours ago [-]
I thought that was the standard in Linux, at least. I'm not sure how they do it in the BSDs.
ricardo81 8 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 8 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 8 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 6 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".

TeMPOraL 59 minutes ago [-]
One has to question the premise of such "smartness" in the system in the first place.
ricardo81 8 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.
TeMPOraL 8 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.
trollied 32 minutes ago [-]
I serve 1Gb of /dev/null to every scraper that tries known CVE endpoints. Fuck 'em.
anyfoo 2 minutes ago [-]
How much is 1 GB*0 bytes? Better serve 1GB of /dev/zero instead! (Or even better, /dev/urandom, because zeroes compress very well and are easy to spot.)
pjc50 7 hours ago [-]
If your machine is on the Internet in any way, you're taking part in the big ongoing global CTF.
TeMPOraL 2 hours ago [-]
True as it may be, it's not the reason my machine is on the Internet.
inetknght 8 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 4 hours 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.

Aissen 8 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.

stabbles 7 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 :(

cryptonector 4 hours 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.

jmclnx 8 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 6 hours ago [-]
Back in the day I used libpam-tmpdir for that purpose - it covered SSH and other services that used PAM.
gnramires 6 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 4 hours ago [-]
Pledge/unveil it's intristic, per software, under OpenBSD.
udev4096 8 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 8 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 8 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 8 hours ago [-]
I think this one was in the "Unix admin horror stories"
stevekemp 6 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 7 hours ago [-]
Wish I'd read that before I did it then.
Joker_vD 8 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 7 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 8 hours ago [-]
You can use /var/tmp for this purpose

It is not cleared between reboots

NekkoDroid 7 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 8 hours ago [-]
Depends on the OS. In OpenBSD, /var/tmp is a symlink to ../tmp and is so is cleaned on reboots and periodically.
akdev1l 7 hours ago [-]
pjmlp 8 hours ago [-]
So here we have again how "Worse is better" works in practice, and how we got here regarding /tmp in 2024.
anthk 8 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 7 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 6 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 7 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 4 hours ago [-]
TMPDIR can be trivially set at $HOME/tmp too with just a file at /etc/profile
danans 4 hours 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?
aidenn0 7 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 7 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 6 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.

CarpaDorada 8 hours ago [-]
Is it possible to configure every user to see /tmp as $USER/.tmp via some Linux isolation method (namespaces)?
0xC0ncord 8 hours ago [-]
This exact thing is possible with pam_namespace.so!
CarpaDorada 8 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 8 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 8 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 8 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.
jauntywundrkind 8 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 8 hours ago [-]
That is very cool, thank you for sharing it.

I wonder if Fedora does this by default?

GoblinSlayer 6 hours ago [-]
Happy debugging, yeah. FastCGI examples usually create sockets in /tmp, but nginx doesn't see them, go figure.
noinsight 41 minutes ago [-]
Fix: JoinsNamespaceOf=
jauntywundrkind 3 hours ago [-]
A more canonical means would be to use the runtime directory. Explicitly setting a Runtime directory= for each would be appropriate.

I get your point. Yeah as a newbie flipping on random options listed under "sandbox" may be bad for you. But this hardly seems like a good dig against a well integrated unit process that has lots on tap to do the job very very well, in a succint manner.

fforflo 6 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 7 hours ago [-]
If you're opening with O_CREAT|O_EXCL, why does it matter whether the filename is predictable?
fanf2 6 hours ago [-]
Denial of service, the next point in that list.
kijin 7 hours ago [-]
Because other processes can periodically check whether a predictable filename is in use, and guess things you'd rather keep private?
johnisgood 7 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 5 hours ago [-]
But you wouldn't need to guess names to do that, since the names of files in /tmp are publicly listable.
layer8 8 hours ago [-]
> Probably the main reason was path-dependence

Nice pun. :)

irunmyownemail 8 hours ago [-]
I use a tmp dir in my home folder on my machines too, I like the idea of tmp.
Starlevel004 6 hours ago [-]
The actual answer is to use O_TMPFILE.
hulitu 8 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 7 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.
Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact
Rendered at 21:42:20 GMT+0000 (Coordinated Universal Time) with Vercel.