Rogier Wolff
1998-Mar-11 08:17 UTC
Re: [linux-security] Towards a solution of tmp-file problems
Hi everyone, Thanks all for your feedback. Here is a reply to most of your comments.... Roger. Chris Evans wrote:> On Mon, 9 Mar 1998, Rogier Wolff wrote:> > not to give those rights away. A non-setuid program should not have to > > worry about buffer overruns (you can crash the program, wow!). It> Just a reminder, that in some cases, it _should_ worry. As a simple recent > real-world example, someone''s ftp client had an overrun that allowed > malicious remote servers to send malformed directory listings, and thus > gain access to the user running the client.Right. Lets generalize this: Anything that interacts with stuff that has lower-security clearance should be "careful". This includes: passwd, lpr: setuid, interaction possible with normal users on the system. inetd, ftpd: network deamons, interaction with unauthenticated remote users. netscape, ftp: userprograms, interaction with unauthenticated remote servers. This does NOT include: ls, cat: userprograms, interact only with system-local stuff. Mark Whitis (whitis@dbd.com) wrote:> > A /tmp that is a symlink to /.tmp/$euid would do the trick.> However, there are some things which are broken by this. One case > which was pointed out to me was the unix domain sockets used by X11.Actually "X11" is broken. It is using /tmp not for temporary files, but for a communications path. The cludge-fix is to have a traditional symlink to a centralized place for all those that still want the unix-domain socket in their private /tmp.> There might also be problems with programs like lpr, in some > situations. Any program or script which calls lpr with a file in > /tmp using the untranslated pathname (this will happen often) might > fail since lpr might interpret the pathname in a different context > since it is suid.If that''s the case, then lpr has a large security hole. If it''s accessing my file as "root" then I can NOW trick it to print other people''s files. William R. Ward (hermit@BayView.COM) wrote: [WRW: Complexity.... Shell has many syntaxes for variable expansion REW: just the "$variable" syntax will be supported. ]> There are definitely situations where ${variable} would be needed. > I strongly recommend you add it. In fact you could even do what > make does and require it (and not support $variable).Actually that''s a very good idea. This way, not just a single character ($) but a two character sequence (${) is used to trigger the special case. Andries Brower (Andries.Brouwer@cwi.nl) wrote:> > How about allowing symlinks with "variable expansion"?> What you describe is a new kind of object. Don''t call it a symlink > - POSIX will soon tell us precisely what the semantics of symlinks > are (does the standard exist already?). Call it a varlink. New type > of object in the filesystem, new semantics.Good idea! Done. Andries, I''m deliberately interpreting your suggestion a little different than you intended. You probably meant that a new set of "flags" (file, directory, symlink, pipe, block-dev, char-dev, ... varlink), on an file-system object would make it a varlink as opposed to a symlink. That would require 1) all the filesystems to be updated 2) And lots of tools. I''m defining a "varlink" as a "symlink that has the "${" sequence embedded. Randolph Bentson (bentson@grieg.holmsjoen.com) wrote:> The "link" operation is atomic and fails even for root if the > destination exists. It''s a rather simple matter to create a file in > /tmp with an effectively unguessable name (using /dev/urandom and > other such) before attempting a link to the desired file name.1) This isn''t as easy for things like shell scripts that need a temporary file. 2) It doesn''t follow the rule "what should be easy actually IS easy". A program that doesn''t interact cross-security boundary shouldn''t need to be written by a security expert. Glynn Clements (glynn@sensei.co.uk) wrote:> > Sometimes a program already checks for the existence of the file, and > > creates it if its not there. This is not atomic, and cannot easily be > > made secure.> Well, you can open() it with [ O_CREAT| ] O_EXCL.- Which will happily create a new file through a symlink... - Which isn''t easliy do-able for shell scripts.> e.g. mkstemp(). Unfortunately the file is created with mode 0666, so > you need to remember to fchown() it.Which Casper Dik just noted is a Posix requirement. Don''t you just LOVE those Posix specs? Grant Kaufmann (grant@intekom.com) wrote:> I believe the solution should:[...]> - Require that the programmer conforms to some programming > guidelines, be it the use of a new system call, checking environment > variables, etc.This is true and acceptable for setuid programs where the requirement "the programmer needs to know about security issues" is a valid one. But joe-user should be able to write a shell script that doesn''t open up his account to mis-use.> > 4) A special "/tmp" directory, that''s private for every userid.> This is the same as option 3. It is also a new filesystem type with > particular characteristics. This would be a problem in that users often > use /tmp as a place to transfer files between each other.So /tmp for two different users aren''t the same anymore. So user2 will have to say: "cp /.tmp/user1/file ." when she gets "/tmp/file: not found".> The direct problem is that a security risk exists when programs > write temporary files to a common location. Indirectly the problem > is that programmers do not have the tools to get around this > problem. Your solution does provide such a tool, but would > respecting $TMPDIR not achieve the same result?Yes. It would go a long way. However: - fixing all applications is a lot of work. (e.g. try getting such a patch into a LARGE package like gcc). - The casual script isn''t affected.> There would need to be a way to identify what the value of the link > is (/usr/cad/cad_$cad_version) as opposed to what it expands to > (/usr/cad/cad_5.0). Without this, administering this would be > difficult.Right. I expect "readlink" to simply return "cad_${cad_version}", without any modifications to ls and the like that would list as such. Programs using explicit "readlink" and then opening "the result" will break. Anybody know a good reason why you would want to do this? (*)> One final question, if you can variable-expand symlinks, why not > standard files as well? Imagine a system with 3 consoles, each using > /dev/mouse, which is actually a link to /dev/mouse_$consolenbr.YES! That''s exactly what I had in mind: the "varlink" feature is not only restricted to fixing a security problem related to /tmp. You''re perfectly welcome to use it for different purposes. I also got reactions from the following people. An extremely short summary follows: Mike Johnson (Mike.Johnson@GSC.GTE.Com): good idea, I''ll betatest. Don Marti (dmarti@electriclichen.com): the varlink could point off the root partition, working towards a read-only root. Greg Alexander (gralexan@indiana.edu): good idea, I''ll betatest. Regards, Roger Wolff. (*) Web servers, when directed to selectively ignore symlinks will probably fall under this category, right? instead of just opening a file, to make sure you ignore the right symlinks, you''ll have to readlink and follow the link yourself. This is a case of "code duplication" (kernel/web deamon) which can be expected to lead to trouble. -- If it''s there and you can see it, it''s REAL |___R.E.Wolff@BitWizard.nl | If it''s there and you can''t see it, it''s TRANSPARENT | Tel: +31-15-2137555 | If it''s not there and you can see it, it''s VIRTUAL |__FAX:_+31-15-2138217 | If it''s not there and you can''t see it, it''s GONE! -- Roy Wilks, 1983 |_____|
Nick Andrew
1998-Mar-11 13:38 UTC
Re: [linux-security] Re: Towards a solution of tmp-file problems
Forwarding a message from Rogier Wolff:> Mark Whitis (whitis@dbd.com) wrote: > > > > A /tmp that is a symlink to /.tmp/$euid would do the trick. > > > However, there are some things which are broken by this. One case > > which was pointed out to me was the unix domain sockets used by X11.Theo De Raadt pointed out (possibly not in this thread) that basing protection on euid is not workable. Although I like the concept of variable expansion in pathnames, I don''t see it as a security mechanism. Please correct me if I misunderstand the basic problem: a process, not particularly security-conscious, needs to be able to open and use one or more temporary files, without the possibility of another process interfering with those files. Suggestions so far include per-user TMPDIRs, fixing all the code to do safe open, and expanding the namespace to make the filename unguessable, Per-user TMPDIRs don''t improve security if a setuid program uses a user''s TMPDIR, which it will if the setuid program has given away privs. Expanding the namespace avoids the symlink problem (e.g. symlink /tmp/aa12345 to /etc/passwd) but leaves temp files open to umask-related problems where a hostile process overwrites a created file. How about this idea, which I don''t recall anybody mentioning yet: truly anonymous temp files. Define a filesystem, directory or path such that open() of any pathname under that root returns a file descriptor to a new inode which is _not linked_ in that filesystem. The file thus opened becomes a truly anonymous file - guaranteed to be newly created and no other process can obtain the same file (except when the file descriptor is explicitly passed by the opening process, through dup(), fork/exec and the like). This is not a solution intended to allow users to share files - sharing and protecting are mutually exclusive requirements; let them share files somewhere else. There are several ways this could be implemented. One, as a new filesystem type known to the kernel. I think it could be implemented fairly readily with userfs backing onto an existing filesystem. Two, as a new semantic for directories, complementary to the 1000 mode. Three, as an additional flag to open() called, say, O_UNLINK. I think the cleanest solution must be O_UNLINK - Unix really needs an API overhaul, and atomic file operations is one of the areas which need a facelift. Dennis Ritchie has been deservedly commended for designing an OS interface which lasted over 20 years, but it''s time to go back and redesign it based on that experience. [REW: Compatibility is VERY important nowadays. re: MSDOS.] I believe this method will require code changes, not sure how much. I see two categories: firstly progs which open a temp file, use it while open and close/unlink it when done. I think these progs should use atomically unlinked files by default. Second category includes progs which open a temp file and perhaps expect to close and reopen the same file later, or pass the pathname to some other program. Such progs would require modification to utilise an atomically unlinked file, unless ... ... unless there''s some way to create a kind of "private namespace" for a process or family of processes. For example the shell running a script could have a private /tmp namespace which would be visible to the shell and all subprocesses, but nobody else. Any process could create a new private namespace and arrange for it to be inherited, and perhaps a mechanism for passing this private namespace to unrelated processes may be useful. [REW: Is this different from using $TMPDIR set to $HOME/tmp?] It could be implemented by a new system call similar to chroot() except unprivileged - but that introduces a new type of object into the system, and other calls would be required to manage instances of this object. It could also be done via (another) modification to open(), and "access" to this private namespace would be equivalent to holding an open file descriptor. Access could then be inherited using normal mechanisms and transferred using normal mechanisms. Nick. -- Zeta Internet SP4 Fax: +61-2-9233-6545 Voice: 9231-9400 G.P.O. Box 3400, Sydney NSW 1043 http://www.zeta.org.au/
Aleph One
1998-Mar-11 18:10 UTC
Re: [linux-security] Re: Re: Towards a solution of tmp-file problems
On Thu, 12 Mar 1998, Nick Andrew wrote:> How about this idea, which I don''t recall anybody mentioning yet: truly > anonymous temp files. Define a filesystem, directory or path such that > open() of any pathname under that root returns a file descriptor to a > new inode which is _not linked_ in that filesystem. The file thus opened > becomes a truly anonymous file - guaranteed to be newly created and > no other process can obtain the same file (except when the file descriptor > is explicitly passed by the opening process, through dup(), fork/exec and > the like).This will break applications that need to stat files to check if other instances of itself are running (e.g. pine).> This is not a solution intended to allow users to share files - sharing and > protecting are mutually exclusive requirements; let them share files > somewhere else.This touches on the core problem of why even though the /tmp problem is as old as UNIX is has never been fixed. There has just never been a standard definition of what /tmp is used for. Every solution everyone has proposed break one of the uses of /tmp. It used for temporary disk space, temporary files, interprocess communication between process of the same uid, IPC between processes of different uids, etc. Why one do you want to give up?> There are several ways this could be implemented. One, as a new filesystem > type known to the kernel. I think it could be implemented fairly readily > with userfs backing onto an existing filesystem. Two, as a new semantic for > directories, complementary to the 1000 mode. Three, as an additional flag > to open() called, say, O_UNLINK. > > I think the cleanest solution must be O_UNLINK - Unix really needs an API > overhaul, and atomic file operations is one of the areas which need a > facelift. Dennis Ritchie has been deservedly commended for designing > an OS interface which lasted over 20 years, but it''s time to go back and > redesign it based on that experience.O_UNLINK would not help. So now instead of simply truncating, overwritting or appending to a file and attacker can now also deleted it by playing with symlinks. What you need is a O_NOSYMLINKS flag to open to tell it to refuse to honor symlinks. But if you add such a flag your must recompile all program you want to protect. If you are going to recompile all those program you might as well fix them to use open correctly in the first place. O_UNLINK is also useless in a directory with the sticky bit on (unless you are root) since you cant delete others (the attacker) files. [REW: (Some of the...) Comments in the source, and, as far as I can see, the source itself, say that O_EXCL in 2.1.x means that no symlinks will be followed on the final stretch. This disagrees with the majority (but not all) of the unices out there, but is required to make things secure. "varlinks" are working over here ;-) ]> Nick. > -- > Zeta Internet SP4 Fax: +61-2-9233-6545 Voice: 9231-9400 > G.P.O. Box 3400, Sydney NSW 1043 http://www.zeta.org.au/ > > -- > ---------------------------------------------------------------------- > Please refer to the information about this list as well as general > information about Linux security at http://www.aoy.com/Linux/Security. > ---------------------------------------------------------------------- > > To unsubscribe: mail -s unsubscribe test-list-request@redhat.com < /dev/null >Aleph One / aleph1@dfw.net http://underground.org/ KeyID 1024/948FD6B5 Fingerprint EE C9 E8 AA CB AF 09 61 8C 39 EA 47 A8 6A B8 01
Grant Kaufmann
1998-Mar-12 09:43 UTC
Re: [linux-security] Re: Re: Re: Towards a solution of tmp-file problems
Aleph One wrote:> > On Thu, 12 Mar 1998, Nick Andrew wrote: > > > This is not a solution intended to allow users to share files - sharing and > > protecting are mutually exclusive requirements; let them share files > > somewhere else. > > This touches on the core problem of why even though the /tmp problem is as > old as UNIX is has never been fixed. There has just never been a standard > definition of what /tmp is used for. Every solution everyone has proposed > break one of the uses of /tmp. It used for temporary disk space, temporary > files, interprocess communication between process of the same uid, > IPC between processes of different uids, etc. Why one do you want to give > up?This is the fundamental issue. /tmp is a common temporary storage location. The _problem_ is that programmers don''t treat it as such. They treat it as a secure storage location. Its a mindset that needs to be changed. By honouring $TMPDIR, it would be a start.> [REW: (Some of the...) Comments in the source, and, as far as I can > see, the source itself, say that O_EXCL in 2.1.x means that no > symlinks will be followed on the final stretch. This disagrees with > the majority (but not all) of the unices out there, but is required to > make things secure. "varlinks" are working over here ;-) ]If we are suggesting a new FS, we''re not really concerned with portability. Would anything break if O_CREAT|O_EXCL was guaranteed by the kernel to be atomic and to not follow links? Several OS''s (at least one, anyway) do support this and it does give the programmer one more secure programming tool. [mod: The example for "at least one" is "Linux-2.1.x". -- REW] -- Grant
Nick Andrew
1998-Mar-12 23:35 UTC
Re: [linux-security] Re: Re: Re: Towards a solution of tmp-file problems
Forwarding a message from Aleph One:> On Thu, 12 Mar 1998, Nick Andrew wrote: > > > How about this idea, which I don''t recall anybody mentioning yet: truly > > anonymous temp files. Define a filesystem, directory or path such that > > open() of any pathname under that root returns a file descriptor to a > > new inode which is _not linked_ in that filesystem. The file thus opened > > becomes a truly anonymous file - guaranteed to be newly created and > > no other process can obtain the same file (except when the file descriptor > > is explicitly passed by the opening process, through dup(), fork/exec and > > the like). > > This will break applications that need to stat files to check if other > instances of itself are running (e.g. pine).See the latter part of my first message in this thread; the part to which you are responding requires that users of unlinked temp files pass a file descriptor to the open temp file, which doesn''t solve the problem for shell scripts, which typically write to a temp file in a subprocess then read from the same temp file in the next subprocess. The latter part of my message suggests a sharing/partitioning scheme in which processes participate in a sharing domain through holding a file descriptor which provides access to a particular sharing domain. This file descriptor typically remains open across fork/exec and so subprocesses can participate in the same sharing domain without having to do anything special (that''s how scripts continue to work). Processes which do not hold the file descriptor are partitioned; that is how we get extra security. A process may participate in multiple sharing domains or in none. If a process does not know about sharing domains, it inherits the sharing domain(s) of its parent by inheriting the open file descriptor(s) which were passed across the exec call. For example: a user''s login process could setup a sharing domain in the filesystem as, say "/tmp". All processes descended from that login process would see a common set of files in /tmp. Say the user runs a setuid process. The setuid process can establish its own sharing domain under "/tmp" and any subprocesses will see a common set of files in /tmp, which will not include the user''s files and the user will not see the setuid processes'' files. The setuid process can safely call programs like "sort" and "gcc" knowing that the temp files which they use cannot be hijacked.> This touches on the core problem of why even though the /tmp problem is as > old as UNIX is has never been fixed. There has just never been a standard > definition of what /tmp is used for. Every solution everyone has proposed > break one of the uses of /tmp. It used for temporary disk space, temporary > files, interprocess communication between process of the same uid, > IPC between processes of different uids, etc. Why one do you want to give > up?Good point. Very good point in fact, which leads to a prerequisite activity: define all the various incompatible uses of /tmp and separate them, so there''s a separate directory for (say) inter-user file sharing compared to private temporary files.> > I think the cleanest solution must be O_UNLINK - Unix really needs an API > > overhaul, and atomic file operations is one of the areas which need a > > facelift. Dennis Ritchie has been deservedly commended for designing > > an OS interface which lasted over 20 years, but it''s time to go back and > > redesign it based on that experience. > > O_UNLINK would not help. So now instead of simply truncating, overwritting > or appending to a file and attacker can now also deleted it by playing > with symlinks. What you need is a O_NOSYMLINKS flag to open to tell it to > refuse to honor symlinks.O_UNLINK is an atomic operation which protects the file after it is open; you are correct that further atomic operations are required to protect the process by giving it certainty that it is opening the file it expects. All this is helpful for processes which are security-conscious, it doesn''t help non-security-conscious processes at all.> [REW: (Some of the...) Comments in the source, and, as far as I can > see, the source itself, say that O_EXCL in 2.1.x means that no > symlinks will be followed on the final stretch. This disagrees with > the majority (but not all) of the unices out there, but is required to > make things secure. "varlinks" are working over here ;-) ]Has anybody done work on how to secure "find"? This is probably the ultimate challenge in protecting against file hacking in /tmp ... to guarantee that I as root can run "find /tmp -user bloggs -exec rm -f {} \;" without deleting anything unexpected; once the correct way to secure that case is known the rest of the solution will probably be clear. Nick. -- Zeta Internet SP4 Fax: +61-2-9233-6545 Voice: 9231-9400 G.P.O. Box 3400, Sydney NSW 1043 http://www.zeta.org.au/