[HN Gopher] Against /tmp
       ___________________________________________________________________
        
       Against /tmp
        
       Author : todsacerdoti
       Score  : 197 points
       Date   : 2024-10-22 12:36 UTC (10 hours ago)
        
 (HTM) web link (dotat.at)
 (TXT) w3m dump (dotat.at)
        
       | Aardwolf wrote:
       | 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
        
         | nullindividual wrote:
         | 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.
        
           | Aardwolf wrote:
           | I use this with a size of a few GB:
           | https://wiki.archlinux.org/title/Tmpfs
        
           | noirscape wrote:
           | 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 wrote:
             | > OS will try to move it in swapspace if memory gets low
             | 
             | That defeats the idea GP presented.
        
               | noirscape wrote:
               | 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 wrote:
               | > 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 wrote:
               | It may or may not be what the OP was talking about,
               | depending on your threat model.
        
               | dspillett wrote:
               | 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.
        
               | cowsandmilk wrote:
               | 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 wrote:
               | Yeah, that's why I think the prime feature of tmpfs is
               | more ephemerality than anything else.
        
               | anyfoo wrote:
               | 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...)
        
           | RiverCrochet wrote:
           | 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.
        
           | akira2501 wrote:
           | > 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.
        
         | pama wrote:
         | The /tmp in RAM does not address any of the vulnerabilities
         | unfortunately.
        
           | Aardwolf wrote:
           | At least the 'tmp cleanup' related ones from the article
        
             | pama wrote:
             | No not really. These are there for long running jobs.
             | Reboot clean up of tmp is not an issue.
        
         | noirscape wrote:
         | 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 wrote:
           | I prefer the explicit /dev/shm for this.
        
         | rnd0 wrote:
         | I thought that was the standard in Linux, at least. I'm not
         | sure how they do it in the BSDs.
        
         | tolciho wrote:
         | 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 wrote:
           | 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.
        
         | cryptonector wrote:
         | Ok, but that's not relevant or responsive to TFA.
        
       | CarpaDorada wrote:
       | Is it possible to configure every user to see /tmp as $USER/.tmp
       | via some Linux isolation method (namespaces)?
        
         | 0xC0ncord wrote:
         | This exact thing is possible with pam_namespace.so!
        
           | CarpaDorada wrote:
           | 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 wrote:
             | 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 wrote:
               | 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 wrote:
         | 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 wrote:
       | 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=P_
       | 
       | > _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 wrote:
         | That is very cool, thank you for sharing it.
         | 
         | I wonder if Fedora does this by default?
        
         | GoblinSlayer wrote:
         | Happy debugging, yeah. FastCGI examples usually create sockets
         | in /tmp, but nginx doesn't see them, go figure.
        
           | jauntywundrkind wrote:
           | 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.
        
           | noinsight wrote:
           | Fix: JoinsNamespaceOf=
        
       | tmountain wrote:
       | 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 wrote:
         | 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 wrote:
           | I think this one was in the "Unix admin horror stories"
        
             | zimpenfish wrote:
             | Wish I'd read that before I did it then.
        
             | stevekemp wrote:
             | 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.
        
         | Joker_vD wrote:
         | > 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?
        
         | akdev1l wrote:
         | You can use /var/tmp for this purpose
         | 
         | It is not cleared between reboots
        
           | SoftTalker wrote:
           | Depends on the OS. In OpenBSD, /var/tmp is a symlink to
           | ../tmp and is so is cleaned on reboots and periodically.
        
             | akdev1l wrote:
             | https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s15.ht
             | m...
             | 
             | Yeah it's a Linux/FHS thing.
        
           | NekkoDroid wrote:
           | 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 :)
        
         | ziml77 wrote:
         | 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.
        
       | jmclnx wrote:
       | 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 wrote:
         | Back in the day I used libpam-tmpdir for that purpose - it
         | covered SSH and other services that used PAM.
        
       | ricardo81 wrote:
       | 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 wrote:
         | 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.
        
           | ricardo81 wrote:
           | 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 wrote:
           | 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 wrote:
           | 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 wrote:
             | One has to question the premise of such "smartness" in the
             | system in the first place.
        
       | Joker_vD wrote:
       | > 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.
        
         | nullindividual wrote:
         | 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?!
        
           | yxhuvud wrote:
           | What system operations exist that need temp storage shouldn't
           | have a separate user anyhow?
        
             | nullindividual wrote:
             | 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 wrote:
               | Services on windows have home folder e.g. in
               | \Windows\ServiceProfiles\LocalService
        
           | gspencley wrote:
           | 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 wrote:
             | > 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 wrote:
             | > 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 wrote:
               | > 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 wrote:
               | Check pledge/unveil under OpenBSD. You get isolated
               | software yet with freedoms.
        
               | marcosdumay wrote:
               | 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 wrote:
           | 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.
        
         | tgv wrote:
         | 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 wrote:
           | 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 wrote:
             | Thanks for that first link, explained some stuff I've been
             | curious about
        
         | cryptonector wrote:
         | /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 wrote:
           | It doesn't have to be, does it? Drop the S_IWOTH from it.
        
             | cryptonector wrote:
             | But you'll have to have all users be members of the group
             | then. That gets you nothing.
        
               | Joker_vD wrote:
               | No you don't have to?
               | joker@e2509h:~/test_tmp$ ll         total 12K
               | drwxr-xr-x  3 joker joker 4.0K Oct 22 22:12 ./
               | drwxr-x--- 11 joker joker 4.0K Oct 22 22:12 ../
               | drwxr-xr-x  3 root  root  4.0K Oct 22 22:13 tmp/
               | joker@e2509h:~/test_tmp$ cd tmp
               | joker@e2509h:~/test_tmp/tmp$ ll         total 12K
               | drwxr-xr-x 3 root  root  4.0K Oct 22 22:13 ./
               | drwxr-xr-x 3 joker joker 4.0K Oct 22 22:12 ../
               | drwxr-xr-x 2 joker joker 4.0K Oct 22 22:13 joker/
               | -rw-r--r-- 1 root  root     0 Oct 22 22:15 z
               | joker@e2509h:~/test_tmp/tmp$ touch x         touch:
               | cannot touch 'x': Permission denied
               | joker@e2509h:~/test_tmp/tmp$ rm z         rm: remove
               | write-protected regular empty file 'z'? y         rm:
               | cannot remove 'z': Permission denied
               | joker@e2509h:~/test_tmp/tmp$ touch joker/x
               | joker@e2509h:~/test_tmp/tmp$ ll joker         total 8.0K
               | drwxr-xr-x 2 joker joker 4.0K Oct 22 22:13 ./
               | drwxr-xr-x 3 root  root  4.0K Oct 22 22:15 ../
               | -rw-r--r-- 1 joker joker    0 Oct 22 22:13 x
               | joker@e2509h:~/test_tmp/tmp$ rm joker/x
               | joker@e2509h:~/test_tmp/tmp$
               | 
               | Looks like it works just fine.
        
       | 0xC0ncord wrote:
       | 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_...
        
         | yjftsjthsd-h wrote:
         | There's also
         | https://www.freedesktop.org/software/systemd/man/latest/syst...
         | to do the same for services if you use systemd.
        
         | aidenn0 wrote:
         | 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.
        
           | zbentley wrote:
           | 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 wrote:
             | 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.
        
           | xerxes901 wrote:
           | /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 wrote:
             | Thanks!
             | 
             | It's exactly what I was looking for, and the world can now
             | continue to improve without breaking any of my workflows :)
        
             | zokier wrote:
             | mount namespace and root directory are bit different things
             | though.
             | 
             | /proc/$PID/ns is the place to look for namespaces
        
           | zokier wrote:
           | nsenter --all --target $PID
           | 
           | or something like that?
           | 
           | https://man7.org/linux/man-pages/man1/nsenter.1.html
        
         | fanf2 wrote:
         | Lovely, another layer of complexity to increase the safety of a
         | fundamental mistake that we can no longer fix!
        
         | cryptonector wrote:
         | 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
        
       | udev4096 wrote:
       | 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
        
         | cryptonector wrote:
         | :)
         | 
         | Don't put . in your PATH, that's for sure.
        
       | layer8 wrote:
       | > Probably the main reason was path-dependence
       | 
       | Nice pun. :)
        
       | hulitu wrote:
       | > Against /Tmp
       | 
       | This is like a pope talking about celibacy.
       | 
       | Did he try to remove /tmp entirely and see how it goes ?
        
         | yjftsjthsd-h wrote:
         | 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.
        
       | Aissen wrote:
       | 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.
        
       | pjmlp wrote:
       | So here we have again how "Worse is better" works in practice,
       | and how we got here regarding /tmp in 2024.
        
         | anthk wrote:
         | 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 wrote:
           | 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.
        
           | tredre3 wrote:
           | > 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 wrote:
             | TMPDIR can be trivially set at $HOME/tmp too with just a
             | file at /etc/profile
        
           | pjmlp wrote:
           | 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
        
       | irunmyownemail wrote:
       | I use a tmp dir in my home folder on my machines too, I like the
       | idea of tmp.
        
       | TeMPOraL wrote:
       | In which people forget that computers have other purposes beyond
       | being boxes for CTF competitions. Shared mutable global state
       | isn't always bad.
        
         | inetknght wrote:
         | > _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.
        
         | pjc50 wrote:
         | If your machine is on the Internet in any way, you're taking
         | part in the big ongoing global CTF.
        
           | TeMPOraL wrote:
           | True as it may be, it's not the reason my machine is on the
           | Internet.
        
         | samatman wrote:
         | 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.
        
         | trollied wrote:
         | I serve 1Gb of /dev/null to every scraper that tries known CVE
         | endpoints. Fuck 'em.
        
           | anyfoo wrote:
           | 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.)
        
       | josephcsible wrote:
       | If you're opening with O_CREAT|O_EXCL, why does it matter whether
       | the filename is predictable?
        
         | kijin wrote:
         | Because other processes can periodically check whether a
         | predictable filename is in use, and guess things you'd rather
         | keep private?
        
           | johnisgood wrote:
           | 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 wrote:
           | But you wouldn't need to guess names to do that, since the
           | names of files in /tmp are publicly listable.
        
         | fanf2 wrote:
         | Denial of service, the next point in that list.
        
         | cryptonector wrote:
         | As u/fanf says, denial of service. The canonical example here
         | would be `/tmp/krb5cc_$UID`, which is where Kerberos libraries
         | keep your Kerberos credentials. If you create that for some
         | other user's UID before they login, they won't be able to use
         | Kerberos (unless they have a clue), causing support calls. This
         | isn't really an issue, but still.
         | 
         | And of course those libraries' code that uses those files had
         | to be written very carefully.
         | 
         | Sure, the more modern thing is to have a daemon called `kcm`
         | that does that and which has an AF_LOCAL socket in...
         | /var/run/, but it's a multi-user-capable daemon, so it doesn't
         | need /var/run/user/${UID}, which as I've noted elsewhere here,
         | is not universally available (for the same reasons that
         | /run/user/${UID} is not either).
        
       | aidenn0 wrote:
       | > 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 wrote:
         | 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 wrote:
           | 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.
        
       | stabbles wrote:
       | 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 :(
        
       | scottlamb wrote:
       | > 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 wrote:
         | 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_.
        
           | zokier wrote:
           | Does k8s guarantee that /tmp is available either?
        
             | cryptonector wrote:
             | Well, I suppose that depends on the images you choose to
             | run, and how you choose to build them, but I've never seen
             | one that didn't have a /tmp. Have you?
        
           | anyfoo wrote:
           | > 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.
        
             | eikenberry wrote:
             | > 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.
             | 
             | How many of these do you have? I have 1 and I have it
             | installed via a flatpak with sandboxing (that has no access
             | to /tmp).
             | 
             | Flatpak's are an implementation of that container model for
             | software on Linux.
        
               | Quekid5 wrote:
               | As an obvious example: You should _not_ trust your
               | browser to have access to all of your file system(s)
               | without explicitly allowing at the time of access. The
               | only thing it should (usually) have access to is your
               | "Downloads" folder... and that's about it.
               | 
               | Browser security would be a _lot_ less time-sensitive if
               | that were the case.
               | 
               | The same logic applies to games, etc. etc. I do _NOT_
               | trust the developers of these things to get things right
               | 100% of the time, so why even take the risk of allowing
               | their programs unfettered access to all of my files? As a
               | dev, I don 't even trust _myself_ to be perfect and I 'd
               | like to be able (in my program) to state up from "my code
               | will never touch anything outside Downloads/" or
               | whatever.
               | 
               | ETA: The point is _minimal_ trust for any given program
               | to do its thing. I 'd like to be even more pithy with
               | something about "trust but verify", but that doesn't
               | quite fit, alas.
        
               | anyfoo wrote:
               | On my phone? Tons. My phone has a boatload of data, and I
               | readily install apps. I don't want one rogue update of a
               | rarely used app (supply chain attacks are very real as we
               | know) to get access to all my text messages and email, or
               | to whatever my banking apps keep as state.
               | 
               | On my Mac? Less, but it happens. But text messages,
               | photos etc. are still inaccessible by anything except the
               | thing's I've explicitly given access.
        
             | cryptonector wrote:
             | Sure, POSIX is basically Unix as standardized over several
             | decades. Unix is 54 years old. Containers are a very recent
             | development. POSIX is behind. But you do have the option to
             | use containers/jails/zones, it's just not POSIX. What does
             | any of that have to do with TFA?
        
               | anyfoo wrote:
               | I just wanted to point out that some unixoid systems
               | (even some who are actually UNIX certified, but that's
               | not really relevant to the issue) employ protection of
               | temporary files _stronger_ than what was suggested in
               | TFA. The containers /jails/zones that you mention are an
               | example of this.
        
         | anyfoo wrote:
         | 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.
        
         | assimpleaspossi wrote:
         | 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
        
         | alkonaut wrote:
         | Windows seemed like a mess to me but it's actually not too bad.
         | Local/roaming per-app data can be separated and the per-user
         | temp would always then be in the local part.
        
       | fforflo wrote:
       | Whenever I find myself needing /tmp, it's usually as a form of
       | IPC shared memory, in which case I use /dev/shm directly.
        
       | gnramires wrote:
       | 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 wrote:
         | Pledge/unveil it's intristic, per software, under OpenBSD.
        
       | Starlevel004 wrote:
       | The actual answer is to use O_TMPFILE.
        
         | cryptonector wrote:
         | Which is not portable. But also if you wanted to find your
         | stuff again in other processes that you can't arrange to
         | inherit shared memory and/or open FDs from the one creating it,
         | then O_TMPFILE is not a relevant answer.
        
       | cryptonector wrote:
       | 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 wrote:
       | 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?
        
       | cedws wrote:
       | 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 wrote:
         | 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.
        
         | ForHackernews wrote:
         | > It's not the 80s anymore where we're logging on to a shared
         | mainframe
         | 
         | It's even worse than that: We're all using the same shared
         | applications on some cloud.
        
       | Myrmornis wrote:
       | On the other hand /tmp is useful for symlinking ~/Downloads to on
       | MacOS since then you never have to clean up your Downloads!
        
       ___________________________________________________________________
       (page generated 2024-10-22 23:01 UTC)