]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fs-util: make sure openat_report_new() initializes return param also on shortcut
authorLennart Poettering <lennart@poettering.net>
Tue, 22 Mar 2022 12:32:38 +0000 (13:32 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 23 Mar 2022 02:38:08 +0000 (11:38 +0900)
Our coding style dictates that return parameters should be initialized
always on success, hence do so here also in the shortcut codepath.

Issue discovered by @fbuihuu:

https://github.com/systemd/systemd/pull/22808/files/ca8503f168d0632c606110da909aba3057777395#r831911069

src/basic/fs-util.c
src/test/test-fs-util.c

index 9d9f265b0f12c7a3db7c932552c5a898988981ea..e7e8ee236bc2825fe387f3a368578613e81bb615 100644 (file)
@@ -1086,17 +1086,25 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) {
 
 int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created) {
         unsigned attempts = 7;
+        int fd;
 
         /* Just like openat(), but adds one thing: optionally returns whether we created the file anew or if
          * it already existed before. This is only relevant if O_CREAT is set without O_EXCL, and thus will
          * shortcut to openat() otherwise */
 
-        if (!FLAGS_SET(flags, O_CREAT) || FLAGS_SET(flags, O_EXCL) || !ret_newly_created)
+        if (!ret_newly_created)
                 return RET_NERRNO(openat(dirfd, pathname, flags, mode));
 
-        for (;;) {
-                int fd;
+        if (!FLAGS_SET(flags, O_CREAT) || FLAGS_SET(flags, O_EXCL)) {
+                fd = openat(dirfd, pathname, flags, mode);
+                if (fd < 0)
+                        return -errno;
 
+                *ret_newly_created = FLAGS_SET(flags, O_CREAT);
+                return fd;
+        }
+
+        for (;;) {
                 /* First, attempt to open without O_CREAT/O_EXCL, i.e. open existing file */
                 fd = openat(dirfd, pathname, flags & ~(O_CREAT | O_EXCL), mode);
                 if (fd >= 0) {
index c93723ad293a0ebe8ea2e7f7ee1a56e6912e6894..f24e97b4ccc956479ee94d21ffa4fc4e499ae931 100644 (file)
@@ -1018,6 +1018,24 @@ TEST(openat_report_new) {
         assert_se(fd >= 0);
         fd = safe_close(fd);
         assert_se(!b);
+
+        fd = openat_report_new(AT_FDCWD, j, O_RDWR, 0666, &b);
+        assert_se(fd >= 0);
+        fd = safe_close(fd);
+        assert_se(!b);
+
+        fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT|O_EXCL, 0666, &b);
+        assert_se(fd == -EEXIST);
+
+        assert_se(unlink(j) >= 0);
+
+        fd = openat_report_new(AT_FDCWD, j, O_RDWR, 0666, &b);
+        assert_se(fd == -ENOENT);
+
+        fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT|O_EXCL, 0666, &b);
+        assert_se(fd >= 0);
+        fd = safe_close(fd);
+        assert_se(b);
 }
 
 static int intro(void) {