From 6e0da36b15927be377635c81d8dd160c6083ca81 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 23 Jun 2023 08:32:23 +0000 Subject: [PATCH] gpt-utils: use open() and close() directly When built and used with Debian 12, write fails like: block dev write failed: Bad file descriptor gpt_set_header: Failed to write back GPT header gpt_disk_commit: Failed to update primary GPT header update_slot_attribute: Failed to write back entry for xbl_a SLOT _a: Failed to mark boot successful due to the fd beeing closed when entering the write function. Directly use open() and close() and avoid using a C++ object for that. Signed-off-by: Neil Armstrong --- gpt-utils.cpp | 65 ++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/gpt-utils.cpp b/gpt-utils.cpp index f0ad56a..36320af 100644 --- a/gpt-utils.cpp +++ b/gpt-utils.cpp @@ -440,24 +440,6 @@ static int gpt_set_header(uint8_t *gpt_header, int fd, return 0; } -struct file { - int fd = -1; - - ~file() - { - if (fd > -1) { - fsync(fd); - close(fd); - } - } - - int open(const char *path) - { - fd = ::open(path, O_RDWR); - return fd; - } -}; - //Read out the GPT header for the disk that contains the partition partname static bool gpt_get_header(const char *partname, enum gpt_instance instance, std::vector *hdr) @@ -465,7 +447,7 @@ static bool gpt_get_header(const char *partname, enum gpt_instance instance, char devpath[PATH_MAX] = { 0 }; off_t hdr_offset = 0; uint32_t block_size = 0; - file file; + int fd; if (!partname) { fprintf(stderr, "%s: Invalid partition name\n", __func__); return false; @@ -478,16 +460,19 @@ static bool gpt_get_header(const char *partname, enum gpt_instance instance, return false; } - if (file.open(devpath) < 0) { + fd = open(devpath, O_RDONLY); + if (fd < 0) { fprintf(stderr, "%s: Failed to open %s: %s\n", __func__, devpath, strerror(errno)); + close(fd); return false; } - block_size = gpt_get_block_size(file.fd); + block_size = gpt_get_block_size(fd); if (block_size == 0) { fprintf(stderr, "%s: Failed to get gpt block size for %s\n", __func__, partname); + close(fd); return false; } @@ -496,20 +481,24 @@ static bool gpt_get_header(const char *partname, enum gpt_instance instance, if (instance == PRIMARY_GPT) hdr_offset = block_size; else - hdr_offset = lseek64(file.fd, 0, SEEK_END) - block_size; + hdr_offset = lseek64(fd, 0, SEEK_END) - block_size; if (hdr_offset < 0) { fprintf(stderr, "%s: Failed to get gpt header offset\n", __func__); + close(fd); return false; } - if (blk_rw(file.fd, 0, hdr_offset, hdr->data(), block_size)) { + if (blk_rw(fd, 0, hdr_offset, hdr->data(), block_size)) { fprintf(stderr, "%s: Failed to read GPT header from device\n", __func__); + close(fd); return false; } + close(fd); + return true; } @@ -596,8 +585,8 @@ static int gpt_set_pentry_arr(uint8_t *hdr, int fd, uint8_t *arr) //disk represented by path dev. Returns 0 on success and -1 on error. int gpt_disk_get_disk_info(const char *dev, struct gpt_disk *disk) { - file file; uint32_t gpt_header_size = 0; + int fd; if (!disk || !dev) { fprintf(stderr, "%s: Invalid arguments\n", __func__); @@ -630,25 +619,28 @@ int gpt_disk_get_disk_info(const char *dev, struct gpt_disk *disk) return -1; } - if (file.open(disk->devpath) < 0) { + fd = open(disk->devpath, O_RDONLY); + if (fd < 0) { fprintf(stderr, "%s: Failed to open %s: %s\n", __func__, disk->devpath, strerror(errno)); return -1; } - gpt_get_pentry_arr(disk->hdr.data(), file.fd, &disk->pentry_arr); + gpt_get_pentry_arr(disk->hdr.data(), fd, &disk->pentry_arr); if (disk->pentry_arr.empty()) { fprintf(stderr, "%s: Failed to obtain partition entry array\n", __func__); + close(fd); return -1; } - gpt_get_pentry_arr(disk->hdr_bak.data(), file.fd, + gpt_get_pentry_arr(disk->hdr_bak.data(), fd, &disk->pentry_arr_bak); if (disk->pentry_arr_bak.empty()) { fprintf(stderr, "%s: Failed to obtain backup partition entry array\n", __func__); + close(fd); return -1; } @@ -660,8 +652,11 @@ int gpt_disk_get_disk_info(const char *dev, struct gpt_disk *disk) GET_4_BYTES(disk->hdr.data() + PARTITION_CRC_OFFSET); disk->pentry_arr_bak_crc = GET_4_BYTES(disk->hdr_bak.data() + PARTITION_CRC_OFFSET); - disk->block_size = gpt_get_block_size(file.fd); + disk->block_size = gpt_get_block_size(fd); disk->is_initialized = GPT_DISK_INIT_MAGIC; + + close(fd); + return 0; } @@ -722,13 +717,15 @@ int gpt_disk_update_crc(struct gpt_disk *disk) //Write the contents of struct gpt_disk back to the actual disk int gpt_disk_commit(struct gpt_disk *disk) { - file file; + int fd; + if (!disk || (disk->is_initialized != GPT_DISK_INIT_MAGIC)) { fprintf(stderr, "%s: Invalid args\n", __func__); return -1; } - if (file.open(disk->devpath) < 0) { + fd = open(disk->devpath, O_RDWR); + if (fd < 0) { fprintf(stderr, "%s: Failed to open %s: %s\n", __func__, disk->devpath, strerror(errno)); return -1; @@ -736,22 +733,26 @@ int gpt_disk_commit(struct gpt_disk *disk) LOGD("%s: Writing back primary GPT header\n", __func__); //Write the primary header - if (gpt_set_header(disk->hdr.data(), file.fd, PRIMARY_GPT) != 0) { + if (gpt_set_header(disk->hdr.data(), fd, PRIMARY_GPT) != 0) { fprintf(stderr, "%s: Failed to update primary GPT header\n", __func__); + close(fd); return -1; } LOGD("%s: Writing back primary partition array\n", __func__); //Write back the primary partition array - if (gpt_set_pentry_arr(disk->hdr.data(), file.fd, + if (gpt_set_pentry_arr(disk->hdr.data(), fd, disk->pentry_arr.data())) { fprintf(stderr, "%s: Failed to write primary GPT partition arr\n", __func__); + close(fd); return -1; } + close(fd); + return 0; }