From ade3d1ee9494af32f4e022e30757318a94b7ee96 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Thu, 24 Jul 2014 14:19:08 -0600 Subject: [PATCH] LU-7276 utils: fix llog_reader loop on empty log If llog_reader tries to read an empty log file (0 bytes) it does not detect this as an error, since it tries to read 0 bytes from the llog and then tries to parse an empty llog header. Return an error if the llog file is smaller than struct llog_log_hdr. Signed-off-by: Andreas Dilger Change-Id: Ife482eb6d73b35f09cc70ca4b79bfd7b053ebb35 Reviewed-on: http://review.whamcloud.com/17627 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Frank Zago Reviewed-by: Olaf Faaland-LLNL Reviewed-by: Oleg Drokin --- lustre/utils/llog_reader.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/lustre/utils/llog_reader.c b/lustre/utils/llog_reader.c index 6ebbe02..4d2f1ff 100644 --- a/lustre/utils/llog_reader.c +++ b/lustre/utils/llog_reader.c @@ -50,7 +50,7 @@ #include #include #include - +#include #include #include #include @@ -208,8 +208,8 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog, struct llog_rec_hdr ***recs, int *recs_number) { - int rc = 0, recs_num, rd; - off_t file_size; + int rc = 0, recs_num, rd = 0; + long long file_size; struct stat st; char *file_buf = NULL, *recs_buf = NULL; struct llog_rec_hdr **recs_pr = NULL; @@ -222,10 +222,14 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog, llapi_error(LLAPI_MSG_ERROR, rc, "Got file stat error."); goto out; } + file_size = st.st_size; - if (file_size == 0) { - rc = -1; - llapi_error(LLAPI_MSG_ERROR, rc, "File is empty."); + if (file_size < sizeof(**llog)) { + llapi_error(LLAPI_MSG_ERROR, rc, + "File too small for llog header: " + "need %zd, size %lld\n", + sizeof(**llog), file_size); + rc = -EIO; goto out; } @@ -237,20 +241,29 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog, } *llog = (struct llog_log_hdr *)file_buf; - rd = read(fd, file_buf, file_size); + do { + rc = read(fd, file_buf + rd, file_size - rd); + if (rc > 0) + rd += rc; + } while (rc > 0 && rd < file_size); + if (rd < file_size) { - rc = -EIO; /*FIXME*/ - llapi_error(LLAPI_MSG_ERROR, rc, "Read file error."); + rc = rc < 0 ? -errno : -EIO; + llapi_error(LLAPI_MSG_ERROR, rc, + "Error reading llog header: need %zd, got %d", + sizeof(**llog), rd); goto clear_file_buf; } /* the llog header not countable here.*/ recs_num = le32_to_cpu((*llog)->llh_count) - 1; - recs_buf = malloc(recs_num * sizeof(struct llog_rec_hdr *)); + recs_buf = malloc(recs_num * sizeof(**recs_pr)); if (recs_buf == NULL) { rc = -ENOMEM; - llapi_error(LLAPI_MSG_ERROR, rc, "Memory Alloc for recs_buf."); + llapi_error(LLAPI_MSG_ERROR, rc, + "Error allocating %zd bytes for recs_buf", + recs_num * sizeof(**recs_pr)); goto clear_file_buf; } recs_pr = (struct llog_rec_hdr **)recs_buf; @@ -263,8 +276,7 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog, int idx; unsigned long offset; - if (ptr + sizeof(struct llog_rec_hdr) > - file_buf + file_size) { + if (ptr + sizeof(**recs_pr) > file_buf + file_size) { rc = -EINVAL; llapi_error(LLAPI_MSG_ERROR, rc, "The log is corrupt (too big at %d)", i); -- 1.8.3.1