]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
loop-util: when open_flags is unspecified derive it from passed in fd
authorLennart Poettering <lennart@poettering.net>
Wed, 21 Jan 2026 21:29:22 +0000 (22:29 +0100)
committerLennart Poettering <lennart@poettering.net>
Sat, 24 Jan 2026 19:51:45 +0000 (20:51 +0100)
src/shared/loop-util.c

index b64953c65d3a88b1297f7276672d4119cd8834c6..8c924296488d2e88484b879aa2280488817fa225 100644 (file)
@@ -431,10 +431,25 @@ static int loop_device_make_internal(
         int r, f_flags;
         struct stat st;
 
+        assert(fd >= 0);
+        assert(open_flags < 0 || IN_SET(open_flags, O_RDWR, O_RDONLY));
         assert(ret);
-        assert(IN_SET(open_flags, O_RDWR, O_RDONLY));
 
-        if (fstat(ASSERT_FD(fd), &st) < 0)
+        f_flags = fcntl(fd, F_GETFL);
+        if (f_flags < 0)
+                return -errno;
+
+        if (open_flags < 0) {
+                /* If open_flags is unset, initialize it from the open fd */
+                if (FLAGS_SET(f_flags, O_PATH))
+                        return log_debug_errno(SYNTHETIC_ERRNO(EBADFD), "Access mode of image file indicates O_PATH, cannot determine read/write flags.");
+
+                open_flags = f_flags & O_ACCMODE_STRICT;
+                if (!IN_SET(open_flags, O_RDWR, O_RDONLY))
+                        return log_debug_errno(SYNTHETIC_ERRNO(EBADFD), "Access mode of image file is write only (?)");
+        }
+
+        if (fstat(fd, &st) < 0)
                 return -errno;
 
         if (S_ISBLK(st.st_mode)) {
@@ -461,10 +476,6 @@ static int loop_device_make_internal(
                         return r;
         }
 
-        f_flags = fcntl(fd, F_GETFL);
-        if (f_flags < 0)
-                return -errno;
-
         if (FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) != FLAGS_SET(f_flags, O_DIRECT)) {
                 /* If LO_FLAGS_DIRECT_IO is requested, then make sure we have the fd open with O_DIRECT, as
                  * that's required. Conversely, if it's off require that O_DIRECT is off too (that's because