From 529a133c390049085db38e7c8f745d650a2626ee Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 10 Jun 2011 10:50:07 -0700 Subject: [PATCH] * movemail.c: Fix race condition and related bugs (Bug#8836). (main) [!MAIL_USE_SYSTEM_LOCK]: Prefer mkstemp to mktemp, as this fixes some race conditions. Report mkstemp/mktemp errno rather than a possibly-garbage errno. Reinitialize the template each time through the loop, as earlier mkstemp/mktemp calls could have trashed it. Pass 0600 (not 0666) to mktemp, for consistency with mkstemp; the permissions don't matter anyway. --- lib-src/ChangeLog | 10 ++++++++++ lib-src/movemail.c | 35 ++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index ff0d3da0a80..ec123e85036 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,13 @@ +2011-06-10 Paul Eggert + + * movemail.c: Fix race condition and related bugs (Bug#8836). + (main) [!MAIL_USE_SYSTEM_LOCK]: Prefer mkstemp to mktemp, as this + fixes some race conditions. Report mkstemp/mktemp errno rather + than a possibly-garbage errno. Reinitialize the template each + time through the loop, as earlier mkstemp/mktemp calls could have + trashed it. Pass 0600 (not 0666) to mktemp, for consistency + with mkstemp; the permissions don't matter anyway. + 2011-06-01 Dan Nicolaescu * emacsclient.c (socket_status): Use constant pointer. diff --git a/lib-src/movemail.c b/lib-src/movemail.c index 4cf97cbac18..e8c09f090f3 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c @@ -168,8 +168,9 @@ main (int argc, char **argv) #ifndef MAIL_USE_SYSTEM_LOCK struct stat st; int tem; - char *lockname, *p; + char *lockname; char *tempname; + size_t inname_dirlen; int desc; #endif /* not MAIL_USE_SYSTEM_LOCK */ @@ -298,26 +299,38 @@ main (int argc, char **argv) to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */ lockname = concat (inname, ".lock", ""); - tempname = (char *) xmalloc (strlen (inname) + strlen ("EXXXXXX") + 1); - strcpy (tempname, inname); - p = tempname + strlen (tempname); - while (p != tempname && !IS_DIRECTORY_SEP (p[-1])) - p--; - *p = 0; - strcpy (p, "EXXXXXX"); - mktemp (tempname); - unlink (tempname); + for (inname_dirlen = strlen (inname); + inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]); + inname_dirlen--) + continue; + tempname = (char *) xmalloc (inname_dirlen + sizeof "EXXXXXX"); while (1) { /* Create the lock file, but not under the lock file name. */ /* Give up if cannot do that. */ - desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0666); + + memcpy (tempname, inname, inname_dirlen); + strcpy (tempname + inname_dirlen, "EXXXXXX"); +#ifdef HAVE_MKSTEMP + desc = mkstemp (tempname); +#else + mktemp (tempname); + if (!*tempname) + desc = -1; + else + { + unlink (tempname); + desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0600); + } +#endif if (desc < 0) { + int mkstemp_errno = errno; char *message = (char *) xmalloc (strlen (tempname) + 50); sprintf (message, "creating %s, which would become the lock file", tempname); + errno = mkstemp_errno; pfatal_with_name (message); } close (desc); -- 2.39.2