[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)