tree-wide: use pwrite_full() for positioned writes

Several places write a buffer at an offset with a single pwrite() or
pwritev(), and fail if the call writes less than the whole buffer. The
lock file of a dynamic user is then truncated to the bytes written, so
it keeps a cut-off user name. memfd_new_and_seal() fails for data larger
than one write() call accepts, which is about 2 GiB on Linux. The other
callers return -EIO, and lose the error that another write would report,
such as ENOSPC.

Use pwrite_full(), which keeps writing until the whole buffer is written
or a write fails. The lock file of a dynamic user is written from two
buffers and uses pwritev_full() instead.

repart writes the verity signature with lseek() and loop_write(). It
uses pwrite_full() as well, which does not move the file offset.

(cherry picked from commit 2fd17cb9eaca00a4dcb9af85a1f485e6d04bda04)
This commit is contained in:
Daan De Meyer
2026-10-16 17:24:51 +01:00
committed by Luca Boccassi
parent 8b9fb1bbec
commit ef565d78af
5 changed files with 44 additions and 61 deletions
+4 -5
View File
@@ -7,6 +7,7 @@
#include "alloc-util.h"
#include "errno-util.h"
#include "fd-util.h"
#include "io-util.h"
#include "memfd-util.h"
#include "process-util.h"
#include "string-util.h"
@@ -132,11 +133,9 @@ int memfd_new_and_seal(const char *name, const void *data, size_t sz) {
return fd;
if (sz > 0) {
ssize_t n = pwrite(fd, data, sz, 0);
if (n < 0)
return -errno;
if ((size_t) n != sz)
return -EIO;
r = pwrite_full(fd, data, sz, 0);
if (r < 0)
return r;
}
r = memfd_set_sealed(fd);