summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-11-09 07:07:11 +0100
committerGitHub <noreply@github.com>2023-11-09 07:07:11 +0100
commit6900d908772a0ce8d294594916dcab578c8136c6 (patch)
treeb52466c672d86d0f854633dac146f420a0eb7c16
parenttest-process-util: Handle unprivileged setrlimit success (diff)
parentbasic/fileio: drop O_CREAT before passing flags to fd_reopen (diff)
downloadsystemd-6900d908772a0ce8d294594916dcab578c8136c6.tar.xz
systemd-6900d908772a0ce8d294594916dcab578c8136c6.zip
Merge pull request #29939 from YHNdnzj/fdopen-independent-mode
basic/fileio: drop O_CREAT in flags passed to fd_reopen
-rw-r--r--src/basic/fd-util.c17
-rw-r--r--src/basic/fileio.c4
2 files changed, 9 insertions, 12 deletions
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index 32289cfd09..0690bcd830 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -761,9 +761,10 @@ finish:
}
int fd_reopen(int fd, int flags) {
- int new_fd, r;
+ int r;
assert(fd >= 0 || fd == AT_FDCWD);
+ assert(!FLAGS_SET(flags, O_CREAT));
/* Reopens the specified fd with new flags. This is useful for convert an O_PATH fd into a regular one, or to
* turn O_RDWR fds into O_RDONLY fds.
@@ -787,19 +788,12 @@ int fd_reopen(int fd, int flags) {
* the same way as the non-O_DIRECTORY case. */
return -ELOOP;
- if (FLAGS_SET(flags, O_DIRECTORY) || fd == AT_FDCWD) {
+ if (FLAGS_SET(flags, O_DIRECTORY) || fd == AT_FDCWD)
/* If we shall reopen the fd as directory we can just go via "." and thus bypass the whole
* magic /proc/ directory, and make ourselves independent of that being mounted. */
- new_fd = openat(fd, ".", flags | O_DIRECTORY);
- if (new_fd < 0)
- return -errno;
-
- return new_fd;
- }
-
- assert(fd >= 0);
+ return RET_NERRNO(openat(fd, ".", flags | O_DIRECTORY));
- new_fd = open(FORMAT_PROC_FD_PATH(fd), flags);
+ int new_fd = open(FORMAT_PROC_FD_PATH(fd), flags);
if (new_fd < 0) {
if (errno != ENOENT)
return -errno;
@@ -825,6 +819,7 @@ int fd_reopen_condition(
int r, new_fd;
assert(fd >= 0);
+ assert(!FLAGS_SET(flags, O_CREAT));
/* Invokes fd_reopen(fd, flags), but only if the existing F_GETFL flags don't match the specified
* flags (masked by the specified mask). This is useful for converting O_PATH fds into real fds if
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 6129461e66..a050b61db4 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -1064,7 +1064,9 @@ int fdopen_independent(int fd, const char *mode, FILE **ret) {
if (mode_flags < 0)
return mode_flags;
- copy_fd = fd_reopen(fd, mode_flags);
+ /* Flags returned by fopen_mode_to_flags might contain O_CREAT, but it doesn't make sense for fd_reopen
+ * since we're working on an existing fd anyway. Let's drop it here to avoid triggering assertion. */
+ copy_fd = fd_reopen(fd, mode_flags & ~O_CREAT);
if (copy_fd < 0)
return copy_fd;