if (r < 0)
return log_unit_error_errno(unit, r, "Failed to serialize parameters: %m");
- if (fseeko(f, 0, SEEK_SET) < 0)
- return log_unit_error_errno(unit, errno, "Failed to reseek on serialization stream: %m");
+ r = finish_serialization_file(f);
+ if (r < 0)
+ return log_unit_error_errno(unit, r, "Failed to finish serialization stream: %m");
r = fd_cloexec(fileno(f), false);
if (r < 0)
#include "clock-warp.h"
#include "conf-parser.h"
#include "confidential-virt.h"
+#include "constants.h"
#include "copy.h"
#include "cpu-set-util.h"
#include "crash-handler.h"
#include "dbus-manager.h"
#include "dbus.h"
-#include "constants.h"
#include "dev-setup.h"
#include "efi-random.h"
#include "efivars.h"
#include "seccomp-util.h"
#include "selinux-setup.h"
#include "selinux-util.h"
+#include "serialize.h"
#include "signal-util.h"
#include "smack-setup.h"
#include "special.h"
assert(ret_f);
assert(ret_fds);
- r = manager_open_serialization(m, &f);
- if (r < 0)
- return log_error_errno(r, "Failed to create serialization file: %m");
-
/* Make sure nothing is really destructed when we shut down */
m->n_reloading++;
bus_manager_send_reloading(m, true);
+ r = manager_open_serialization(m, &f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create serialization file: %m");
+
fds = fdset_new();
if (!fds)
return log_oom();
if (r < 0)
return r;
- if (fseeko(f, 0, SEEK_SET) < 0)
- return log_error_errno(errno, "Failed to rewind serialization fd: %m");
+ r = finish_serialization_file(f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to finish serialization file: %m");
r = fd_cloexec(fileno(f), false);
if (r < 0)
return r;
}
- r = fflush_and_check(f);
- if (r < 0)
- return log_error_errno(r, "Failed to flush serialization: %m");
-
r = bus_fdset_add_all(m, fds);
if (r < 0)
return log_error_errno(r, "Failed to add bus sockets to serialization: %m");
#include "rlimit-util.h"
#include "rm-rf.h"
#include "selinux-util.h"
+#include "serialize.h"
#include "signal-util.h"
#include "socket-util.h"
#include "special.h"
if (r < 0)
return r;
- if (fseeko(f, 0, SEEK_SET) < 0)
- return log_error_errno(errno, "Failed to seek to beginning of serialization: %m");
+ r = finish_serialization_file(f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to finish serialization: %m");
/* 💀 This is the point of no return, from here on there is no way back. 💀 */
reloading = NULL;
}
if (callbacks) {
- if (lseek(fd, 0, SEEK_SET) < 0)
- return log_error_errno(errno, "Failed to seek on serialization fd: %m");
+ r = finish_serialization_fd(fd);
+ if (r < 0)
+ return log_error_errno(r, "Failed to finish serialization fd: %m");
r = callbacks[STDOUT_GENERATE](TAKE_FD(fd), callback_args[STDOUT_GENERATE]);
if (r < 0)
if (!callbacks)
return 0;
- if (lseek(fd, 0, SEEK_SET) < 0)
- return log_error_errno(errno, "Failed to rewind serialization fd: %m");
+ r = finish_serialization_fd(fd);
+ if (r < 0)
+ return log_error_errno(r, "Failed to finish serialization fd: %m");
r = callbacks[STDOUT_CONSUME](TAKE_FD(fd), callback_args[STDOUT_CONSUME]);
if (r < 0)
return log_error_errno(r, "Failed to parse returned data: %m");
+
return 0;
}
int open_serialization_fd(const char *ident) {
assert(ident);
- int fd = memfd_new(ident);
+ int fd = memfd_new_full(ident, MFD_ALLOW_SEALING);
if (fd < 0)
return fd;
return -errno;
*ret = TAKE_PTR(f);
-
return 0;
}
+
+int finish_serialization_fd(int fd) {
+ assert(fd >= 0);
+
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ return -errno;
+
+ return memfd_set_sealed(fd);
+}
+
+int finish_serialization_file(FILE *f) {
+ int r;
+
+ assert(f);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ return r;
+
+ if (fseeko(f, 0, SEEK_SET) < 0)
+ return -errno;
+
+ int fd = fileno(f);
+ if (fd < 0)
+ return -EBADF;
+
+ return memfd_set_sealed(fd);
+}
int open_serialization_fd(const char *ident);
int open_serialization_file(const char *ident, FILE **ret);
+
+int finish_serialization_fd(int fd);
+int finish_serialization_file(FILE *f);
assert_se(fd >= 0);
assert_se(write(fd, "test\n", 5) == 5);
+
+ assert_se(finish_serialization_fd(fd) >= 0);
}
TEST(open_serialization_file) {
assert_se(f);
assert_se(fwrite("test\n", 1, 5, f) == 5);
+
+ assert_se(finish_serialization_file(f) >= 0);
}
TEST(fd_move_above_stdio) {