diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-20 04:02:51 +0000 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-22 13:50:44 +0000 |
| commit | 6838db4647b600bf5b356429f54850bf801e7ba4 (patch) | |
| tree | cc98541897703d2949af27dc050cad8cba5061a0 /util/nvmutil/lib/io.c | |
| parent | f50ffd6bb13c04cb185fb6311f8875582bf18388 (diff) | |
WIP: hardened mktemp
i'm pretty much nearly there. still no dir support,
only files.
i won't keep amending now - will do more, then
squash later.
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/nvmutil/lib/io.c')
| -rw-r--r-- | util/nvmutil/lib/io.c | 131 |
1 files changed, 77 insertions, 54 deletions
diff --git a/util/nvmutil/lib/io.c b/util/nvmutil/lib/io.c index 5769dd05..87163359 100644 --- a/util/nvmutil/lib/io.c +++ b/util/nvmutil/lib/io.c @@ -21,7 +21,7 @@ void open_gbe_file(void) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct commands *cmd = &x->cmd[x->i]; struct xfile *f = &x->f; @@ -29,12 +29,12 @@ open_gbe_file(void) xopen(&f->gbe_fd, f->fname, cmd->flags | O_BINARY | - O_NOFOLLOW | O_CLOEXEC, &f->gbe_st); + O_NOFOLLOW | O_CLOEXEC | O_NOCTTY, &f->gbe_st); if (f->gbe_st.st_nlink > 1) err(EINVAL, "%s: warning: file has multiple (%lu) hard links\n", - f->fname, (unsigned long)f->gbe_st.st_nlink); + f->fname, (size_t)f->gbe_st.st_nlink); if (f->gbe_st.st_nlink == 0) err(EIO, "%s: file unlinked while open", f->fname); @@ -69,7 +69,7 @@ open_gbe_file(void) void copy_gbe(void) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct xfile *f = &x->f; read_file(); @@ -77,19 +77,19 @@ copy_gbe(void) if (f->gbe_file_size == SIZE_8KB) return; - memcpy(f->buf + (unsigned long)GBE_PART_SIZE, - f->buf + (unsigned long)(f->gbe_file_size >> 1), - (unsigned long)GBE_PART_SIZE); + memcpy(f->buf + (size_t)GBE_PART_SIZE, + f->buf + (size_t)(f->gbe_file_size >> 1), + (size_t)GBE_PART_SIZE); } void read_file(void) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct xfile *f = &x->f; struct stat _st; - long _r; + ssize_t _r; /* read main file */ @@ -141,11 +141,11 @@ read_file(void) void write_gbe_file(void) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct commands *cmd = &x->cmd[x->i]; struct xfile *f = &x->f; - unsigned long p; + size_t p; unsigned char update_checksum; if ((cmd->flags & O_ACCMODE) == O_RDONLY) @@ -171,25 +171,25 @@ write_gbe_file(void) } void -rw_gbe_file_part(unsigned long p, int rw_type, +rw_gbe_file_part(size_t p, int rw_type, const char *rw_type_str) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct commands *cmd = &x->cmd[x->i]; struct xfile *f = &x->f; - long rval; + ssize_t rval; off_t file_offset; - unsigned long gbe_rw_size; + size_t gbe_rw_size; unsigned char *mem_offset; gbe_rw_size = cmd->rw_size; if (rw_type < IO_PREAD || rw_type > IO_PWRITE) err(errno, "%s: %s: part %lu: invalid rw_type, %d", - f->fname, rw_type_str, (unsigned long)p, rw_type); + f->fname, rw_type_str, (size_t)p, rw_type); mem_offset = gbe_mem_offset(p, rw_type_str); file_offset = (off_t)gbe_file_offset(p, rw_type_str); @@ -199,17 +199,17 @@ rw_gbe_file_part(unsigned long p, int rw_type, if (rval == -1) err(errno, "%s: %s: part %lu", - f->fname, rw_type_str, (unsigned long)p); + f->fname, rw_type_str, (size_t)p); - if ((unsigned long)rval != gbe_rw_size) + if ((size_t)rval != gbe_rw_size) err(EIO, "%s: partial %s: part %lu", - f->fname, rw_type_str, (unsigned long)p); + f->fname, rw_type_str, (size_t)p); } void write_to_gbe_bin(void) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct commands *cmd = &x->cmd[x->i]; struct xfile *f = &x->f; @@ -240,14 +240,20 @@ write_to_gbe_bin(void) saved_errno = errno; if (close_on_eintr(f->tmp_fd) == -1) { + f->tmp_fd = -1; + fprintf(stderr, "FAIL: %s: close\n", f->tname); f->io_err_gbe_bin = 1; } + f->tmp_fd = -1; if (close_on_eintr(f->gbe_fd) == -1) { + f->gbe_fd = -1; + fprintf(stderr, "FAIL: %s: close\n", f->fname); f->io_err_gbe_bin = 1; } + f->gbe_fd = -1; errno = saved_errno; @@ -274,8 +280,10 @@ write_to_gbe_bin(void) /* removed by rename */ - if (f->tname != NULL) + if (f->tname != NULL) { free(f->tname); + f->tname = NULL; + } f->tname = NULL; } @@ -292,15 +300,15 @@ write_to_gbe_bin(void) } void -check_written_part(unsigned long p) +check_written_part(size_t p) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct commands *cmd = &x->cmd[x->i]; struct xfile *f = &x->f; - long rval; + ssize_t rval; - unsigned long gbe_rw_size; + size_t gbe_rw_size; off_t file_offset; unsigned char *mem_offset; @@ -328,7 +336,7 @@ check_written_part(unsigned long p) if (rval == -1) f->rw_check_err_read[p] = f->io_err_gbe = 1; - else if ((unsigned long)rval != gbe_rw_size) + else if ((size_t)rval != gbe_rw_size) f->rw_check_partial_read[p] = f->io_err_gbe = 1; else if (memcmp(mem_offset, f->pad, gbe_rw_size) != 0) f->rw_check_bad_part[p] = f->io_err_gbe = 1; @@ -359,10 +367,10 @@ check_written_part(unsigned long p) void report_io_err_rw(void) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct xfile *f = &x->f; - unsigned long p; + size_t p; if (!f->io_err_gbe) return; @@ -374,22 +382,22 @@ report_io_err_rw(void) if (f->rw_check_err_read[p]) fprintf(stderr, "%s: pread: p%lu (post-verification)\n", - f->fname, (unsigned long)p); + f->fname, (size_t)p); if (f->rw_check_partial_read[p]) fprintf(stderr, "%s: partial pread: p%lu (post-verification)\n", - f->fname, (unsigned long)p); + f->fname, (size_t)p); if (f->rw_check_bad_part[p]) fprintf(stderr, "%s: pwrite: corrupt write on p%lu\n", - f->fname, (unsigned long)p); + f->fname, (size_t)p); if (f->rw_check_err_read[p] || f->rw_check_partial_read[p]) { fprintf(stderr, "%s: p%lu: skipped checksum verification " "(because read failed)\n", - f->fname, (unsigned long)p); + f->fname, (size_t)p); continue; } @@ -402,7 +410,7 @@ report_io_err_rw(void) fprintf(stderr, "BAD"); fprintf(stderr, " checksum in p%lu on-disk.\n", - (unsigned long)p); + (size_t)p); if (f->post_rw_checksum[p]) { fprintf(stderr, @@ -415,7 +423,7 @@ report_io_err_rw(void) int gbe_mv(void) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct xfile *f = &x->f; int rval; @@ -490,8 +498,11 @@ gbe_mv(void) if (fsync_on_eintr(dest_fd) == -1) goto ret_gbe_mv; - if (close_on_eintr(dest_fd) == -1) + if (close_on_eintr(dest_fd) == -1) { + dest_fd = -1; goto ret_gbe_mv; + } + dest_fd = -1; if (rename(dest_tmp, f->fname) == -1) goto ret_gbe_mv; @@ -501,25 +512,37 @@ gbe_mv(void) goto ret_gbe_mv; } - free(dest_tmp); + if (dest_tmp != NULL) { + free(dest_tmp); + dest_tmp = NULL; + } + dest_tmp = NULL; ret_gbe_mv: + /* TODO: this whole section is bloat. + it can be generalised + */ + if (f->gbe_fd > -1) { - if (close_on_eintr(f->gbe_fd) < 0) + if (close_on_eintr(f->gbe_fd) < 0) { + f->gbe_fd = -1; rval = -1; + } + f->gbe_fd = -1; + if (fsync_dir(f->fname) < 0) { f->io_err_gbe_bin = 1; rval = -1; } - f->gbe_fd = -1; } if (f->tmp_fd > -1) { - if (close_on_eintr(f->tmp_fd) < 0) + if (close_on_eintr(f->tmp_fd) < 0) { + f->tmp_fd = -1; rval = -1; - + } f->tmp_fd = -1; } @@ -552,9 +575,9 @@ ret_gbe_mv: * and it is *also* used during file I/O. */ unsigned char * -gbe_mem_offset(unsigned long p, const char *f_op) +gbe_mem_offset(size_t p, const char *f_op) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct xfile *f = &x->f; off_t gbe_off; @@ -563,7 +586,7 @@ gbe_mem_offset(unsigned long p, const char *f_op) GBE_PART_SIZE, GBE_WORK_SIZE); return (unsigned char *) - (f->buf + (unsigned long)gbe_off); + (f->buf + (size_t)gbe_off); } /* I/O operations filtered here. These operations must @@ -571,9 +594,9 @@ gbe_mem_offset(unsigned long p, const char *f_op) * within the GbE file, and write 4KB of data. */ off_t -gbe_file_offset(unsigned long p, const char *f_op) +gbe_file_offset(size_t p, const char *f_op) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct xfile *f = &x->f; off_t gbe_file_half_size; @@ -585,10 +608,10 @@ gbe_file_offset(unsigned long p, const char *f_op) } off_t -gbe_x_offset(unsigned long p, const char *f_op, const char *d_type, +gbe_x_offset(size_t p, const char *f_op, const char *d_type, off_t nsize, off_t ncmp) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct xfile *f = &x->f; off_t off; @@ -608,14 +631,14 @@ gbe_x_offset(unsigned long p, const char *f_op, const char *d_type, return off; } -long -rw_gbe_file_exact(int fd, unsigned char *mem, unsigned long nrw, +ssize_t +rw_gbe_file_exact(int fd, unsigned char *mem, size_t nrw, off_t off, int rw_type) { - struct xstate *x = xstatus(0, NULL); + struct xstate *x = xstatus(); struct xfile *f = &x->f; - long r; + ssize_t r; if (io_args(fd, mem, nrw, off, rw_type) == -1) return -1; @@ -624,17 +647,17 @@ rw_gbe_file_exact(int fd, unsigned char *mem, unsigned long nrw, if (mem < f->buf) goto err_rw_gbe_file_exact; - if ((unsigned long)(mem - f->buf) >= GBE_WORK_SIZE) + if ((size_t)(mem - f->buf) >= GBE_WORK_SIZE) goto err_rw_gbe_file_exact; } if (off < 0 || off >= f->gbe_file_size) goto err_rw_gbe_file_exact; - if (nrw > (unsigned long)(f->gbe_file_size - off)) + if (nrw > (size_t)(f->gbe_file_size - off)) goto err_rw_gbe_file_exact; - if (nrw > (unsigned long)GBE_PART_SIZE) + if (nrw > (size_t)GBE_PART_SIZE) goto err_rw_gbe_file_exact; r = rw_file_exact(fd, mem, nrw, off, rw_type, |
