Upstream-Status: Backport The patch to fix CVE-2009-1214 A security flaw was found in the screen utility in the way it used to create one particular temporary file. An attacker could use this flaw to perform a symlink attack. Fix race condition creating temporary file Reference: https://bugzilla.redhat.com/show_bug.cgi?id=492104 Signed-off-by: Chenyang Guo --- fileio.c | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) --- a/fileio.c +++ b/fileio.c @@ -414,6 +414,14 @@ int dump; } public = !strcmp(fn, DEFAULT_BUFFERFILE); # ifdef HAVE_LSTAT + /* + * Note: In the time between lstat() and open()/remove() below are + * called, the file can be created/removed/modified. Therefore the + * information lstat() returns is taken into consideration, but not + * relied upon. In particular, the open()/remove() calls can fail, and + * the code must account for that. Symlink attack could be mounted if + * the code is changed carelessly. --rdancer 2009-01-11 + */ exists = !lstat(fn, &stb); if (public && exists && (S_ISLNK(stb.st_mode) || stb.st_nlink > 1)) { @@ -432,28 +440,36 @@ int dump; #ifdef COPY_PASTE if (dump == DUMP_EXCHANGE && public) { + /* + * Setting umask to zero is a bad idea -- the user surely doesn't + * expect a publicly readable file in a publicly readable directory + * --rdancer 2009-01-11 + */ + /* old_umask = umask(0); + */ # ifdef HAVE_LSTAT if (exists) - { - if ((fd = open(fn, O_WRONLY, 0666)) >= 0) - { - if (fstat(fd, &stb2) == 0 && stb.st_dev == stb2.st_dev && stb.st_ino == stb2.st_ino) - ftruncate(fd, 0); - else - { - close(fd); - fd = -1; - } - } - } - else - fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0666); - f = fd >= 0 ? fdopen(fd, mode) : 0; + if (remove(fn) == -1) + { + /* Error */ + debug2("WriteFile: File exists and remove(%s) failed: %s\n", + fn, strerror(errno)); + UserReturn(0); + } # else - f = fopen(fn, mode); + (void) remove(fn); # endif + /* + * No r/w permissions for anybody but the user, as the file may be in + * a public directory -- if the user chooses, they can chmod the file + * afterwards. --rdancer 2008-01-11 + */ + fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0600); + f = fd >= 0 ? fdopen(fd, mode) : 0; + /* umask(old_umask); + */ } else #endif /* COPY_PASTE */