Merge pull request #31727 from YHNdnzj/homed-followup

data-fd-util: some cleanups
This commit is contained in:
Mike Yuan
2024-03-13 13:10:34 +08:00
committed by GitHub
13 changed files with 48 additions and 45 deletions
-2
View File
@@ -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)
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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);
}
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+20 -20
View File
@@ -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;
+8 -3
View File
@@ -2,15 +2,20 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
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);
+5 -5
View File
@@ -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);
+1 -1
View File
@@ -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);
+5 -5
View File
@@ -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);