diff --git a/src/basic/env-util.c b/src/basic/env-util.c index 7608f90a4a..9e74ba0f0f 100644 --- a/src/basic/env-util.c +++ b/src/basic/env-util.c @@ -1140,9 +1140,7 @@ int setenvf(const char *name, bool overwrite, const char *valuef, ...) { return RET_NERRNO(unsetenv(name)); va_start(ap, valuef); - DISABLE_WARNING_FORMAT_NONLITERAL; r = vasprintf(&value, valuef, ap); - REENABLE_WARNING; va_end(ap); if (r < 0) diff --git a/src/basic/fileio.c b/src/basic/fileio.c index 001c19378e..3aadb4bfab 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -32,7 +32,7 @@ #include "tmpfile-util.h" /* The maximum size of the file we'll read in one go in read_full_file() (64M). */ -#define READ_FULL_BYTES_MAX (64U*1024U*1024U - 1U) +#define READ_FULL_BYTES_MAX (64U * U64_MB - UINT64_C(1)) /* Used when a size is specified for read_full_file() with READ_FULL_FILE_UNBASE64 or _UNHEX */ #define READ_FULL_FILE_ENCODED_STRING_AMPLIFICATION_BOUNDARY 3 @@ -45,7 +45,7 @@ * exponentially in a loop. We use a size limit of 4M-2 because 4M-1 is the maximum buffer that /proc/sys/ * allows us to read() (larger reads will fail with ENOMEM), and we want to read one extra byte so that we * can detect EOFs. */ -#define READ_VIRTUAL_BYTES_MAX (4U*1024U*1024U - 2U) +#define READ_VIRTUAL_BYTES_MAX (4U * U64_MB - UINT64_C(2)) int fdopen_unlocked(int fd, const char *options, FILE **ret) { assert(ret); diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index fbc5fce128..11f93b0c80 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1444,7 +1444,7 @@ static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *er static int reply_dump_by_fd(sd_bus_message *message, char *dump) { _cleanup_close_ int fd = -EBADF; - fd = acquire_data_fd(dump, strlen(dump), 0); + fd = acquire_data_fd(dump); if (fd < 0) return fd; diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 91c7d41266..0db13bfa88 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -410,7 +410,7 @@ static int setup_input( case EXEC_INPUT_DATA: { int fd; - fd = acquire_data_fd(context->stdin_data, context->stdin_data_size, 0); + fd = acquire_data_fd_full(context->stdin_data, context->stdin_data_size, /* flags = */ 0); if (fd < 0) return fd; diff --git a/src/home/homed-home.c b/src/home/homed-home.c index f3c72926d7..edde6fafd3 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -1258,7 +1258,7 @@ static int home_start_work( if (r < 0) return r; - stdin_fd = acquire_data_fd(formatted, strlen(formatted), 0); + stdin_fd = acquire_data_fd(formatted); if (stdin_fd < 0) return stdin_fd; diff --git a/src/home/homework-cifs.c b/src/home/homework-cifs.c index 5d8713111e..eb87b37915 100644 --- a/src/home/homework-cifs.c +++ b/src/home/homework-cifs.c @@ -76,7 +76,7 @@ int home_setup_cifs( pid_t mount_pid; int exit_status; - passwd_fd = acquire_data_fd(*pw, strlen(*pw), /* flags= */ 0); + passwd_fd = acquire_data_fd(*pw); if (passwd_fd < 0) return log_error_errno(passwd_fd, "Failed to create data FD for password: %m"); @@ -94,7 +94,7 @@ int home_setup_cifs( r = setenvf("PASSWD_FD", /* overwrite= */ true, "%d", passwd_fd); if (r < 0) { - log_error_errno(errno, "Failed to set $PASSWD_FD: %m"); + log_error_errno(r, "Failed to set $PASSWD_FD: %m"); _exit(EXIT_FAILURE); } diff --git a/src/oom/oomd-manager-bus.c b/src/oom/oomd-manager-bus.c index 0581d58016..7d2edb5561 100644 --- a/src/oom/oomd-manager-bus.c +++ b/src/oom/oomd-manager-bus.c @@ -22,7 +22,7 @@ static int bus_method_dump_by_fd(sd_bus_message *message, void *userdata, sd_bus if (r < 0) return r; - fd = acquire_data_fd(dump, strlen(dump), 0); + fd = acquire_data_fd(dump); if (fd < 0) return fd; diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 88e1249b8e..3f54914591 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -627,7 +627,7 @@ static int method_dump_memory_state_by_fd(sd_bus_message *message, void *userdat if (r < 0) return r; - fd = acquire_data_fd(dump, dump_size, 0); + fd = acquire_data_fd_full(dump, dump_size, /* flags = */ 0); if (fd < 0) return fd; diff --git a/src/shared/data-fd-util.c b/src/shared/data-fd-util.c index b939206d82..adc7d7417e 100644 --- a/src/shared/data-fd-util.c +++ b/src/shared/data-fd-util.c @@ -20,16 +20,15 @@ #include "tmpfile-util.h" /* When the data is smaller or equal to 64K, try to place the copy in a memfd/pipe */ -#define DATA_FD_MEMORY_LIMIT (64U*1024U) +#define DATA_FD_MEMORY_LIMIT (64U * U64_KB) /* If memfd/pipe didn't work out, then let's use a file in /tmp up to a size of 1M. If it's large than that use /var/tmp instead. */ -#define DATA_FD_TMP_LIMIT (1024U*1024U) +#define DATA_FD_TMP_LIMIT (1U * U64_MB) -int acquire_data_fd(const void *data, size_t size, unsigned flags) { - _cleanup_close_pair_ int pipefds[2] = EBADF_PAIR; +int acquire_data_fd_full(const void *data, size_t size, DataFDFlags flags) { _cleanup_close_ int fd = -EBADF; - int isz = 0, r; ssize_t n; + int r; assert(data || size == 0); @@ -52,24 +51,25 @@ int acquire_data_fd(const void *data, size_t size, unsigned flags) { * It sucks a bit that depending on the situation we return very different objects here, but that's Linux I * figure. */ - if (size == 0 && ((flags & ACQUIRE_NO_DEV_NULL) == 0)) + if (size == SIZE_MAX) + size = strlen(data); + + if (size == 0 && !FLAGS_SET(flags, ACQUIRE_NO_DEV_NULL)) /* As a special case, return /dev/null if we have been called for an empty data block */ return RET_NERRNO(open("/dev/null", O_RDONLY|O_CLOEXEC|O_NOCTTY)); - if ((flags & ACQUIRE_NO_MEMFD) == 0) { + if (!FLAGS_SET(flags, ACQUIRE_NO_MEMFD)) { fd = memfd_new_and_seal("data-fd", data, size); - if (fd < 0) { - if (ERRNO_IS_NOT_SUPPORTED(fd)) - goto try_pipe; - + if (fd < 0 && !ERRNO_IS_NOT_SUPPORTED(fd)) return fd; - } - - return TAKE_FD(fd); + if (fd >= 0) + return TAKE_FD(fd); } -try_pipe: - if ((flags & ACQUIRE_NO_PIPE) == 0) { + if (!FLAGS_SET(flags, ACQUIRE_NO_PIPE)) { + _cleanup_close_pair_ int pipefds[2] = EBADF_PAIR; + int isz; + if (pipe2(pipefds, O_CLOEXEC|O_NONBLOCK) < 0) return -errno; @@ -106,7 +106,7 @@ try_pipe: } try_dev_shm: - if ((flags & ACQUIRE_NO_TMPFILE) == 0) { + if (!FLAGS_SET(flags, ACQUIRE_NO_TMPFILE)) { fd = open("/dev/shm", O_RDWR|O_TMPFILE|O_CLOEXEC, 0500); if (fd < 0) goto try_dev_shm_without_o_tmpfile; @@ -122,7 +122,7 @@ try_dev_shm: } try_dev_shm_without_o_tmpfile: - if ((flags & ACQUIRE_NO_REGULAR) == 0) { + if (!FLAGS_SET(flags, ACQUIRE_NO_REGULAR)) { char pattern[] = "/dev/shm/data-fd-XXXXXX"; fd = mkostemp_safe(pattern); @@ -179,7 +179,7 @@ int copy_data_fd(int fd) { * that we use the reported regular file size only as a hint, given that there are plenty special files in * /proc and /sys which report a zero file size but can be read from. */ - if (!S_ISREG(st.st_mode) || st.st_size < DATA_FD_MEMORY_LIMIT) { + if (!S_ISREG(st.st_mode) || (uint64_t) st.st_size < DATA_FD_MEMORY_LIMIT) { /* Try a memfd first */ copy_fd = memfd_new("data-fd"); @@ -252,7 +252,7 @@ int copy_data_fd(int fd) { } /* If we have reason to believe this will fit fine in /tmp, then use that as first fallback. */ - if ((!S_ISREG(st.st_mode) || st.st_size < DATA_FD_TMP_LIMIT) && + if ((!S_ISREG(st.st_mode) || (uint64_t) st.st_size < DATA_FD_TMP_LIMIT) && (DATA_FD_MEMORY_LIMIT + remains_size) < DATA_FD_TMP_LIMIT) { off_t f; diff --git a/src/shared/data-fd-util.h b/src/shared/data-fd-util.h index 6d99209421..d77e09fb06 100644 --- a/src/shared/data-fd-util.h +++ b/src/shared/data-fd-util.h @@ -2,15 +2,20 @@ #pragma once #include +#include -enum { +typedef enum DataFDFlags { ACQUIRE_NO_DEV_NULL = 1 << 0, ACQUIRE_NO_MEMFD = 1 << 1, ACQUIRE_NO_PIPE = 1 << 2, ACQUIRE_NO_TMPFILE = 1 << 3, ACQUIRE_NO_REGULAR = 1 << 4, -}; +} DataFDFlags; + +int acquire_data_fd_full(const void *data, size_t size, DataFDFlags flags); +static inline int acquire_data_fd(const void *data) { + return acquire_data_fd_full(data, SIZE_MAX, 0); +} -int acquire_data_fd(const void *data, size_t size, unsigned flags); int copy_data_fd(int fd); int memfd_clone_fd(int fd, const char *name, int mode); diff --git a/src/test/test-data-fd-util.c b/src/test/test-data-fd-util.c index aa68132e45..6d1cfe6289 100644 --- a/src/test/test-data-fd-util.c +++ b/src/test/test-data-fd-util.c @@ -17,7 +17,7 @@ static void test_acquire_data_fd_one(unsigned flags) { char rbuffer[sizeof(wbuffer)]; int fd; - fd = acquire_data_fd("foo", 3, flags); + fd = acquire_data_fd_full("foo", 3, flags); assert_se(fd >= 0); zero(rbuffer); @@ -26,7 +26,7 @@ static void test_acquire_data_fd_one(unsigned flags) { fd = safe_close(fd); - fd = acquire_data_fd("", 0, flags); + fd = acquire_data_fd_full("", SIZE_MAX, flags); assert_se(fd >= 0); zero(rbuffer); @@ -37,7 +37,7 @@ static void test_acquire_data_fd_one(unsigned flags) { random_bytes(wbuffer, sizeof(wbuffer)); - fd = acquire_data_fd(wbuffer, sizeof(wbuffer), flags); + fd = acquire_data_fd_full(wbuffer, sizeof(wbuffer), flags); assert_se(fd >= 0); zero(rbuffer); @@ -98,14 +98,14 @@ TEST(copy_data_fd) { fd1 = safe_close(fd1); fd2 = safe_close(fd2); - fd1 = acquire_data_fd("hallo", 6, 0); + fd1 = acquire_data_fd("hallo"); assert_se(fd1 >= 0); fd2 = copy_data_fd(fd1); assert_se(fd2 >= 0); safe_close(fd1); - fd1 = acquire_data_fd("hallo", 6, 0); + fd1 = acquire_data_fd("hallo"); assert_se(fd1 >= 0); assert_equal_fd(fd1, fd2); diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c index 5dd9e48c80..cd4ce83597 100644 --- a/src/test/test-fd-util.c +++ b/src/test/test-fd-util.c @@ -170,7 +170,7 @@ TEST(rearrange_stdio) { assert_se(fd_move_above_stdio(0) == 3); } assert_se(open("/dev/full", O_WRONLY|O_CLOEXEC) == 0); - assert_se(acquire_data_fd("foobar", 6, 0) == 2); + assert_se(acquire_data_fd("foobar") == 2); assert_se(rearrange_stdio(2, 0, 1) >= 0); diff --git a/src/test/test-varlink.c b/src/test/test-varlink.c index 65e7dfafe9..cd9c593613 100644 --- a/src/test/test-varlink.c +++ b/src/test/test-varlink.c @@ -123,8 +123,8 @@ static int method_passfd(Varlink *link, JsonVariant *parameters, VarlinkMethodFl test_fd(yy, "bar", 3); test_fd(zz, "quux", 4); - _cleanup_close_ int vv = acquire_data_fd("miau", 4, 0); - _cleanup_close_ int ww = acquire_data_fd("wuff", 4, 0); + _cleanup_close_ int vv = acquire_data_fd("miau"); + _cleanup_close_ int ww = acquire_data_fd("wuff"); assert_se(vv >= 0); assert_se(ww >= 0); @@ -275,9 +275,9 @@ static void *thread(void *arg) { assert_se(json_variant_integer(json_variant_by_key(o, "sum")) == 88 + 99); assert_se(!e); - int fd1 = acquire_data_fd("foo", 3, 0); - int fd2 = acquire_data_fd("bar", 3, 0); - int fd3 = acquire_data_fd("quux", 4, 0); + int fd1 = acquire_data_fd("foo"); + int fd2 = acquire_data_fd("bar"); + int fd3 = acquire_data_fd("quux"); assert_se(fd1 >= 0); assert_se(fd2 >= 0);