locking: prevent a symlink attack by not opening an existing lock file

If in between the unlink() in delete_lockfile() and the fopen() in
write_lockfile() some other process creates a symlink in the place
of the lock file, then the fopen() could unexpectedly overwite a
root-owned file (when the user is root).

This basically reverts the previous commit, b4299f4f, but makes the
code a bit conciser.
master
Benno Schulenberg 2020-05-20 16:17:30 +02:00
parent b4299f4f4e
commit 10800ee410
1 changed files with 9 additions and 3 deletions

View File

@ -129,6 +129,7 @@ bool write_lockfile(const char *lockfilename, const char *filename, bool modifie
struct passwd *mypwuid = getpwuid(myuid);
char myhostname[32];
struct stat fileinfo;
int fd;
FILE *filestream;
char *lockdata;
size_t wroteamt;
@ -150,12 +151,17 @@ bool write_lockfile(const char *lockfilename, const char *filename, bool modifie
if (!delete_lockfile(lockfilename))
return FALSE;
/* Create lock file (or truncate existing one) and open it for writing. */
filestream = fopen(lockfilename, "wb");
/* Create the lockfile -- do not accept an existing one. */
fd = open(lockfilename, O_WRONLY|O_CREAT|O_EXCL, RW_FOR_ALL);
if (filestream == NULL) {
if (fd > 0)
filestream = fdopen(fd, "wb");
if (fd < 0 || filestream == NULL) {
statusline(MILD, _("Error writing lock file %s: %s"),
lockfilename, strerror(errno));
if (fd > 0)
close(fd);
return FALSE;
}