From 95726c5204768b5837d38a0d4118ba5a36047e2a Mon Sep 17 00:00:00 2001 From: Enrico Joerns Date: Fri, 30 Aug 2024 08:47:30 +0200 Subject: [PATCH] src/hash_index: fix hash_index fd ownership handling When calling r_hash_index_open(), the ownership of the file descriptor provided should be handed over to the hash index and will be later closed in r_hash_index_free(). Thus, the file descriptor provided must not be closed by the calling code anymore. In other code, this is done by setting data_fd = -1; after successfully opening the hash index. In generate_adaptive_data() however, this manual resetting of the pointer was missing and the fd was closed manually in later error handling. This could lead to cases where a double-call of g_close() on the same pointer happened. This was wrong anyway but results in a critical error in RAUC since glib version 2.75.0 which comes with a more pickier g_close() handling: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2964 Fix this and add a hint to the function documentation. Signed-off-by: Enrico Joerns --- include/hash_index.h | 4 ++++ src/bundle.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/hash_index.h b/include/hash_index.h index a5f8d2a4a..25646e201 100644 --- a/include/hash_index.h +++ b/include/hash_index.h @@ -38,6 +38,10 @@ typedef struct { * If an existing hash index file is provided via 'hashes_filename', this will * be used instead of building a new index. * + * If creating the hash index succeeded, the ownership of the provided file + * descriptor must be 'transferred' to the hash index by manually setting the + * provided file descriptor to -1! + * * @param label label for hash index (used for debugging/identification) * @param data_fd open file descriptor of file to hash * @param hashes_filename name of existing hash index file to use instead, or NULL diff --git a/src/bundle.c b/src/bundle.c index d15277567..1c5ae7a7a 100644 --- a/src/bundle.c +++ b/src/bundle.c @@ -422,13 +422,16 @@ static gboolean generate_adaptive_data(RaucManifest *manifest, const gchar *dir, g_close(fd, NULL); return FALSE; } + fd = -1; /* belongs to idx now */ if (!r_hash_index_export(index, indexpath, &ierror)) { g_propagate_prefixed_error( error, ierror, "Failed to write hash index for %s: ", image->filename); - g_close(fd, NULL); + if (fd >= 0) { + g_close(fd, NULL); + } return FALSE; }