Introduce loop_read_exact helper
Usually when using loop_read(), we want to read the full buffer. Add a helper that mirrors loop_write(), and returns 0 when full buffer was read, and an error otherwise. Use -ENODATA for the short read, to distinguish it from a read error.
This commit is contained in:
parent
ad7bcf526d
commit
a6dcc7e592
|
@ -725,7 +725,6 @@ static bool automount_check_gc(Unit *u) {
|
||||||
static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
|
static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
|
||||||
union autofs_v5_packet_union packet;
|
union autofs_v5_packet_union packet;
|
||||||
Automount *a = AUTOMOUNT(userdata);
|
Automount *a = AUTOMOUNT(userdata);
|
||||||
ssize_t l;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(a);
|
assert(a);
|
||||||
|
@ -736,12 +735,9 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
|
r = loop_read_exact(a->pipe_fd, &packet, sizeof(packet), true);
|
||||||
if (l != sizeof(packet)) {
|
if (r < 0) {
|
||||||
if (l < 0)
|
log_unit_error_errno(UNIT(a)->id, r, "Invalid read from pipe: %m");
|
||||||
log_unit_error_errno(UNIT(a)->id, l, "Invalid read from pipe: %m");
|
|
||||||
else
|
|
||||||
log_unit_error(UNIT(a)->id, "Invalid read from pipe: short read");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,6 @@ static int generate(char id[34], const char *root) {
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
sd_id128_t buf;
|
sd_id128_t buf;
|
||||||
char *q;
|
char *q;
|
||||||
ssize_t k;
|
|
||||||
const char *vm_id, *dbus_machine_id;
|
const char *vm_id, *dbus_machine_id;
|
||||||
|
|
||||||
assert(id);
|
assert(id);
|
||||||
|
@ -77,11 +76,10 @@ static int generate(char id[34], const char *root) {
|
||||||
/* First, try reading the D-Bus machine id, unless it is a symlink */
|
/* First, try reading the D-Bus machine id, unless it is a symlink */
|
||||||
fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
k = loop_read(fd, id, 33, false);
|
r = loop_read_exact(fd, id, 33, false);
|
||||||
safe_close(fd);
|
safe_close(fd);
|
||||||
|
|
||||||
if (k == 33 && id[32] == '\n') {
|
if (r >= 0 && id[32] == '\n') {
|
||||||
|
|
||||||
id[32] = 0;
|
id[32] = 0;
|
||||||
if (id128_is_valid(id)) {
|
if (id128_is_valid(id)) {
|
||||||
id[32] = '\n';
|
id[32] = '\n';
|
||||||
|
@ -119,14 +117,14 @@ static int generate(char id[34], const char *root) {
|
||||||
|
|
||||||
r = detect_vm(&vm_id);
|
r = detect_vm(&vm_id);
|
||||||
if (r > 0 && streq(vm_id, "kvm")) {
|
if (r > 0 && streq(vm_id, "kvm")) {
|
||||||
char uuid[37];
|
char uuid[36];
|
||||||
|
|
||||||
fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
k = loop_read(fd, uuid, 36, false);
|
r = loop_read_exact(fd, uuid, 36, false);
|
||||||
safe_close(fd);
|
safe_close(fd);
|
||||||
|
|
||||||
if (k >= 36) {
|
if (r >= 0) {
|
||||||
r = shorten_uuid(id, uuid);
|
r = shorten_uuid(id, uuid);
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
log_info("Initializing machine ID from KVM UUID.");
|
log_info("Initializing machine ID from KVM UUID.");
|
||||||
|
@ -162,7 +160,8 @@ static int get_valid_machine_id(int fd, char id[34]) {
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
assert(id);
|
assert(id);
|
||||||
|
|
||||||
if (loop_read(fd, id_to_validate, 33, false) == 33 && id_to_validate[32] == '\n') {
|
if (loop_read_exact(fd, id_to_validate, 33, false) >= 0 &&
|
||||||
|
id_to_validate[32] == '\n') {
|
||||||
id_to_validate[32] = 0;
|
id_to_validate[32] = 0;
|
||||||
|
|
||||||
if (id128_is_valid(id_to_validate)) {
|
if (id128_is_valid(id_to_validate)) {
|
||||||
|
|
|
@ -589,14 +589,12 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ssize_t n, m;
|
ssize_t m;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
n = read(fdf, &header, sizeof(header));
|
r = loop_read_exact(fdf, &header, sizeof(header), false);
|
||||||
if (n < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return r;
|
||||||
if (n != sizeof(header))
|
|
||||||
return errno ? -errno : -EIO;
|
|
||||||
|
|
||||||
m = le32toh(header);
|
m = le32toh(header);
|
||||||
if (m == 0)
|
if (m == 0)
|
||||||
|
@ -618,12 +616,9 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
|
||||||
if (!GREEDY_REALLOC(buf, buf_size, m))
|
if (!GREEDY_REALLOC(buf, buf_size, m))
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
errno = 0;
|
r = loop_read_exact(fdf, buf, m, false);
|
||||||
n = loop_read(fdf, buf, m, false);
|
if (r < 0)
|
||||||
if (n < 0)
|
return r;
|
||||||
return n;
|
|
||||||
if (n != m)
|
|
||||||
return errno ? -errno : -EIO;
|
|
||||||
|
|
||||||
r = LZ4_decompress_safe_continue(&lz4_data, buf, out, m, 4*LZ4_BUFSIZE);
|
r = LZ4_decompress_safe_continue(&lz4_data, buf, out, m, 4*LZ4_BUFSIZE);
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
|
@ -636,9 +631,9 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
|
||||||
return -EFBIG;
|
return -EFBIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = loop_write(fdt, out, r, false);
|
r = loop_write(fdt, out, r, false);
|
||||||
if (n < 0)
|
if (r < 0)
|
||||||
return n;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug("LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)",
|
log_debug("LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)",
|
||||||
|
|
|
@ -1286,7 +1286,6 @@ static int setup_keys(void) {
|
||||||
#ifdef HAVE_GCRYPT
|
#ifdef HAVE_GCRYPT
|
||||||
size_t mpk_size, seed_size, state_size, i;
|
size_t mpk_size, seed_size, state_size, i;
|
||||||
uint8_t *mpk, *seed, *state;
|
uint8_t *mpk, *seed, *state;
|
||||||
ssize_t l;
|
|
||||||
int fd = -1, r;
|
int fd = -1, r;
|
||||||
sd_id128_t machine, boot;
|
sd_id128_t machine, boot;
|
||||||
char *p = NULL, *k = NULL;
|
char *p = NULL, *k = NULL;
|
||||||
|
@ -1351,10 +1350,9 @@ static int setup_keys(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("Generating seed...");
|
log_info("Generating seed...");
|
||||||
l = loop_read(fd, seed, seed_size, true);
|
r = loop_read_exact(fd, seed, seed_size, true);
|
||||||
if (l < 0 || (size_t) l != seed_size) {
|
if (r < 0) {
|
||||||
log_error_errno(EIO, "Failed to read random seed: %m");
|
log_error_errno(r, "Failed to read random seed: %m");
|
||||||
r = -EIO;
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,9 +108,9 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||||
static thread_local bool saved_machine_id_valid = false;
|
static thread_local bool saved_machine_id_valid = false;
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
char buf[33];
|
char buf[33];
|
||||||
ssize_t k;
|
|
||||||
unsigned j;
|
unsigned j;
|
||||||
sd_id128_t t;
|
sd_id128_t t;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert_return(ret, -EINVAL);
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
|
@ -123,13 +123,9 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
k = loop_read(fd, buf, 33, false);
|
r = loop_read_exact(fd, buf, 33, false);
|
||||||
if (k < 0)
|
if (r < 0)
|
||||||
return (int) k;
|
return r;
|
||||||
|
|
||||||
if (k != 33)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
if (buf[32] !='\n')
|
if (buf[32] !='\n')
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
|
@ -157,10 +153,10 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||||
static thread_local bool saved_boot_id_valid = false;
|
static thread_local bool saved_boot_id_valid = false;
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
char buf[36];
|
char buf[36];
|
||||||
ssize_t k;
|
|
||||||
unsigned j;
|
unsigned j;
|
||||||
sd_id128_t t;
|
sd_id128_t t;
|
||||||
char *p;
|
char *p;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert_return(ret, -EINVAL);
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
|
@ -173,22 +169,19 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
k = loop_read(fd, buf, 36, false);
|
r = loop_read_exact(fd, buf, 36, false);
|
||||||
if (k < 0)
|
if (r < 0)
|
||||||
return (int) k;
|
return r;
|
||||||
|
|
||||||
if (k != 36)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
for (j = 0, p = buf; j < 16; j++) {
|
for (j = 0, p = buf; j < 16; j++) {
|
||||||
int a, b;
|
int a, b;
|
||||||
|
|
||||||
if (p >= buf + k - 1)
|
if (p >= buf + 35)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
if (*p == '-') {
|
if (*p == '-') {
|
||||||
p++;
|
p++;
|
||||||
if (p >= buf + k - 1)
|
if (p >= buf + 35)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1163,9 +1163,9 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
|
|
||||||
k = loop_read(fd, buf, 36, false);
|
r = loop_read_exact(fd, buf, 36, false);
|
||||||
safe_close(fd);
|
safe_close(fd);
|
||||||
if (k != 36)
|
if (k < 0)
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
|
|
||||||
k = send(pair[1], buf, 36, MSG_NOSIGNAL);
|
k = send(pair[1], buf, 36, MSG_NOSIGNAL);
|
||||||
|
|
|
@ -2326,6 +2326,17 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
n = loop_read(fd, buf, nbytes, do_poll);
|
||||||
|
if (n < 0)
|
||||||
|
return n;
|
||||||
|
if ((size_t) n != nbytes)
|
||||||
|
return -EIO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
||||||
const uint8_t *p = buf;
|
const uint8_t *p = buf;
|
||||||
|
|
||||||
|
@ -2580,8 +2591,9 @@ char* dirname_malloc(const char *path) {
|
||||||
|
|
||||||
int dev_urandom(void *p, size_t n) {
|
int dev_urandom(void *p, size_t n) {
|
||||||
static int have_syscall = -1;
|
static int have_syscall = -1;
|
||||||
int r, fd;
|
|
||||||
ssize_t k;
|
_cleanup_close_ fd = -1;
|
||||||
|
int r;
|
||||||
|
|
||||||
/* Gathers some randomness from the kernel. This call will
|
/* Gathers some randomness from the kernel. This call will
|
||||||
* never block, and will always return some data from the
|
* never block, and will always return some data from the
|
||||||
|
@ -2616,22 +2628,14 @@ int dev_urandom(void *p, size_t n) {
|
||||||
return -errno;
|
return -errno;
|
||||||
} else
|
} else
|
||||||
/* too short read? */
|
/* too short read? */
|
||||||
return -EIO;
|
return -ENODATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return errno == ENOENT ? -ENOSYS : -errno;
|
return errno == ENOENT ? -ENOSYS : -errno;
|
||||||
|
|
||||||
k = loop_read(fd, p, n, true);
|
return loop_read_exact(fd, p, n, true);
|
||||||
safe_close(fd);
|
|
||||||
|
|
||||||
if (k < 0)
|
|
||||||
return (int) k;
|
|
||||||
if ((size_t) k != n)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize_srand(void) {
|
void initialize_srand(void) {
|
||||||
|
|
|
@ -432,6 +432,7 @@ int sigaction_many(const struct sigaction *sa, ...);
|
||||||
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
|
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
|
||||||
|
|
||||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
|
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||||
|
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
|
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
|
||||||
|
|
||||||
bool is_device_path(const char *path);
|
bool is_device_path(const char *path);
|
||||||
|
|
Loading…
Reference in a new issue