alsactl: Fix race at creating a lock file

A race at creating a lock file in state_lock() was discovered
recently: namely, between the first open(O_RDWR) and the second
open(O_RDWR|O_CREAT|O_EXCL) calls, another alsactl invocation may
already create a lock file, then the second open() will return EEXIST,
which isn't handled properly and treated as a fatal error.

In this patch, we check EEXIST case and try again open() with O_RDWR.
This must succeed usually, and if it fails, handle finally as the
fatal error.

BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1179904
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2020-12-11 23:46:23 +01:00
parent 878e1a7c0f
commit c53f7cd038

View file

@ -63,13 +63,18 @@ static int state_lock_(const char *file, int lock, int timeout, int _fd)
if (fd < 0) { if (fd < 0) {
if (errno == EBUSY || errno == EAGAIN) { if (errno == EBUSY || errno == EAGAIN) {
sleep(1); sleep(1);
} else { continue;
}
if (errno == EEXIST) {
fd = open(nfile, O_RDWR);
if (fd >= 0)
break;
}
err = -errno; err = -errno;
goto out; goto out;
} }
} }
} }
}
if (fd < 0 && timeout <= 0) { if (fd < 0 && timeout <= 0) {
err = -EBUSY; err = -EBUSY;
goto out; goto out;