From ade392429a7682b918777ba7eb210f3789c98b4a Mon Sep 17 00:00:00 2001 From: jikai Date: Mon, 29 Apr 2024 16:43:51 +0800 Subject: [PATCH 22/22] fix bug for potential config/seccomp/ocihook write error Signed-off-by: jikai --- src/lcrcontainer_extend.c | 18 ++++++++++++------ src/utils.c | 30 ++++++++++++++++++++++++++++++ src/utils.h | 1 + 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/lcrcontainer_extend.c b/src/lcrcontainer_extend.c index d70f5a6..261cf1d 100644 --- a/src/lcrcontainer_extend.c +++ b/src/lcrcontainer_extend.c @@ -352,6 +352,7 @@ static int lcr_spec_write_seccomp_line(int fd, const char *seccomp) char *line = NULL; int ret = -1; int nret; + ssize_t nwritten = -1; if (strlen(seccomp) > SIZE_MAX - strlen("lxc.seccomp.profile") - 3 - 1) { ERROR("the length of lxc.seccomp is too long!"); @@ -375,7 +376,8 @@ static int lcr_spec_write_seccomp_line(int fd, const char *seccomp) nret = (int)(len - 1); } line[nret] = '\n'; - if (write(fd, line, len) == -1) { + nwritten = lcr_util_write_nointr_in_total(fd, line, len); + if (nwritten < 0 || (size_t)nwritten != len) { SYSERROR("Write file failed"); goto cleanup; } @@ -391,7 +393,7 @@ static char *lcr_save_seccomp_file(const char *bundle, const char *seccomp_conf) char *real_seccomp = NULL; int fd = -1; int nret; - ssize_t written_cnt; + ssize_t nwritten = -1; nret = snprintf(seccomp, sizeof(seccomp), "%s/seccomp", bundle); if (nret < 0 || (size_t)nret >= sizeof(seccomp)) { @@ -410,9 +412,9 @@ static char *lcr_save_seccomp_file(const char *bundle, const char *seccomp_conf) goto cleanup; } - written_cnt = write(fd, seccomp_conf, strlen(seccomp_conf)); + nwritten = lcr_util_write_nointr(fd, seccomp_conf, strlen(seccomp_conf)); close(fd); - if (written_cnt == -1) { + if (nwritten < 0 || (size_t)nwritten != strlen(seccomp_conf)) { SYSERROR("write seccomp_conf failed"); goto cleanup; } @@ -710,6 +712,7 @@ static int lcr_spec_write_config(int fd, const struct lcr_list *lcr_conf) lcr_config_item_t *item = it->elem; int nret; size_t encode_len; + ssize_t nwritten = -1; if (item != NULL) { if (strlen(item->value) > ((SIZE_MAX - strlen(item->name)) - 4)) { goto cleanup; @@ -737,7 +740,8 @@ static int lcr_spec_write_config(int fd, const struct lcr_list *lcr_conf) encode_len = strlen(line_encode); line_encode[encode_len] = '\n'; - if (write(fd, line_encode, encode_len + 1) == -1) { + nwritten = lcr_util_write_nointr_in_total(fd, line_encode, encode_len + 1); + if (nwritten < 0 || (size_t)nwritten != encode_len + 1) { SYSERROR("Write file failed"); goto cleanup; } @@ -862,6 +866,7 @@ static int lcr_write_file(const char *path, const char *data, size_t len) char *real_path = NULL; int fd = -1; int ret = -1; + ssize_t nwritten = -1; if (path == NULL || strlen(path) == 0 || data == NULL || len == 0) { return -1; @@ -879,7 +884,8 @@ static int lcr_write_file(const char *path, const char *data, size_t len) goto out_free; } - if (write(fd, data, len) == -1) { + nwritten = lcr_util_write_nointr_in_total(fd, data, len); + if (nwritten < 0 || (size_t)nwritten != len) { SYSERROR("write data to %s failed", real_path); goto out_free; } diff --git a/src/utils.c b/src/utils.c index b999509..1279f8a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1040,6 +1040,36 @@ int lcr_util_build_dir(const char *name) return 0; } +ssize_t lcr_util_write_nointr_in_total(int fd, const char *buf, size_t count) +{ + size_t nwritten; + + if (buf == NULL) { + return -1; + } + + if (count > SSIZE_MAX) { + ERROR("Too large data to write"); + return -1; + } + + for (nwritten = 0; nwritten < count;) { + ssize_t nret; + nret = write(fd, buf + nwritten, count - nwritten); + if (nret < 0) { + if (errno == EINTR || errno == EAGAIN) { + continue; + } else { + return nret; + } + } else { + nwritten += nret; + } + } + + return (ssize_t)nwritten; +} + /* util write nointr */ ssize_t lcr_util_write_nointr(int fd, const void *buf, size_t count) { diff --git a/src/utils.h b/src/utils.h index 2fe4f1e..d248c39 100644 --- a/src/utils.h +++ b/src/utils.h @@ -206,6 +206,7 @@ char *lcr_util_string_append(const char *post, const char *pre); char *lcr_util_string_split_prefix(size_t prefix_len, const char *file); int lcr_util_build_dir(const char *name); +ssize_t lcr_util_write_nointr_in_total(int fd, const char *buf, size_t count); ssize_t lcr_util_write_nointr(int fd, const void *buf, size_t count); ssize_t lcr_util_read_nointr(int fd, void *buf, size_t count); -- 2.34.1