]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
fuse2fs: fix lockfile creation, again
authorDarrick J. Wong <djwong@kernel.org>
Tue, 8 Jul 2025 17:33:33 +0000 (10:33 -0700)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 31 Jul 2025 14:41:55 +0000 (10:41 -0400)
On closer examination of the lockfile code, there is still a fatal flaw
in the locking logic.  This is born out by the fact that you can run:

# truncate -s 300m /tmp/a
# mkfs.ext2 /tmp/a
# fuse2fs -o kernel /tmp/a /mnt -o lockfile=/tmp/fuselock
# fuse2fs -o kernel /tmp/a /mnt -o lockfile=/tmp/fuselock

and the second mount attempt succeeds where it really shouldn't.  This
is due to the use of fopen(..., "w"), because "w" means "truncate or
create".  It does /not/ imply O_CREAT | O_EXCL, which fails if the file
already exists.  Theoretically that could have been done with mode
string "wx", but that's a glibc extension.

Fix this by calling open() directly with the O_ modes that we want.

Cc: linux-ext4@vger.kernel.org # v1.47.3-rc3
Fixes: e50fbaa4d156a6 ("fuse2fs: clean up the lockfile handling")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Link: https://lore.kernel.org/r/20250708173333.GD2672022@frogsfrogsfrogs
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
misc/fuse2fs.c

index b7201f7c8ed18542eaeddcae51623182da520006..ff8d4668cee21716ffdd982abef92307637d34e9 100644 (file)
@@ -4473,11 +4473,15 @@ int main(int argc, char *argv[])
        }
 
        if (fctx.lockfile) {
-               FILE *lockfile = fopen(fctx.lockfile, "w");
                char *resolved;
-
-               if (!lockfile) {
-                       err = errno;
+               int lockfd;
+
+               lockfd = open(fctx.lockfile, O_RDWR | O_CREAT | O_EXCL, 0400);
+               if (lockfd < 0) {
+                       if (errno == EEXIST)
+                               err = EWOULDBLOCK;
+                       else
+                               err = errno;
                        err_printf(&fctx, "%s: %s: %s\n", fctx.lockfile,
                                   _("opening lockfile failed"),
                                   strerror(err));
@@ -4485,7 +4489,7 @@ int main(int argc, char *argv[])
                        ret |= 32;
                        goto out;
                }
-               fclose(lockfile);
+               close(lockfd);
 
                resolved = realpath(fctx.lockfile, NULL);
                if (!resolved) {