Bugtraq mailing list archives
Re: Temporary Files (was Re: mktemp() and friends)
From: chet () odin INS CWRU Edu (Chet Ramey)
Date: Fri, 3 Jan 1997 11:01:11 -0500
Under bash this can be avoided theoretically: set -C exec > /tmp/foo if ! test -f /dev/fd/1; then error... fi There are two bugs in bash which makes this unsafe. The bash manual tells you that tests to /dev/fd/n apply to the file descriptor n but in fact they apply to the real /dev/fd/n if the OS supports the /dev/fd filesystem. On Solaris /dev/fd/n is always a device special file which makes the above test fail in all cases.
I'm still thinking about this one, so the `bug' still exists.
The other bug is that noclobber is not implemented atomically. Here is the code. Redirect->flags contains O_TRUNC | O_WRONLY | O_CREAT here: r = stat (redirectee_word, &finfo); if (r == 0 && (S_ISREG (finfo.st_mode))) { free (redirectee_word); return (NOCLOBBER_REDIRECT); } /* If the file was not present, make sure we open it exclusively so that if it is created before we open it, our open will fail. */ if (r != 0) redirect->flags |= O_EXCL; fd = open (redirectee_word, redirect->flags, 0666); As you can see bash will happily truncate any symlink created between the stat and open. I have already mailed the bash maintainer about these bugs.
The current (unreleased post bash-2.0) bash code adds a couple of checks to this. The O_EXCL is still in there only if the file does not exist at stat(2) time. If the file exists and is not a regular file, O_EXCL is not used. O_TRUNC is turned off. This preserves POSIX.2 compatibility. If the open succeeds, a check is done using fstat(2) to ensure that it still points to the same non-regular file that stat(2) checked. If the file opened is suddenly a regular file or a different special file, bash assumes that the file has changed underneath it and returns an error.
Of course the right way to do that is to never use O_TRUNC with noclobber, try O_WRONLY | O_CREAT | O_EXCL first, and if that fails, open it with O_WRONLY, fstat the returned file descriptor and close it and fail if it is a regular file.
The current bash approach is very similar, with additional checks. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer Chet Ramey, Case Western Reserve University Internet: chet () po CWRU Edu
Current thread:
- Re: Temporary Files (was Re: mktemp() and friends) Zoltan Hidvegi (Dec 26)
- Re: Temporary Files (was Re: mktemp() and friends) Chet Ramey (Jan 03)