Re: [PATCH] object-file: use `container_of()` to convert from base types
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Feb 22, 2026, 07:07 UTC
- Message-ID
- <xmqqms11qmsj.fsf@gitster.g>
- In-Reply-To
- <20260218210120.1146078-1-jltobler@gmail.com>
Justin Tobler <jltobler@gmail.com> writes:
Show 8 quoted lines
> static void prepare_loose_object_transaction(struct odb_transaction *base)
> {
> - struct odb_transaction_files *transaction = (struct odb_transaction_files *)base;
> + struct odb_transaction_files *transaction =
> + container_of(base, struct odb_transaction_files, base);
>
> /*
> * We lazily create the temporary object directoryThis conversion triggers undefined behaviour sanitizer. We see in the post-context:
if (!transaction || transaction->objdir) return;
which means the caller can feed NULL as base. Taking 0 offset is unfortunately a no-no for a NULL pointer.
Unfortunately, this patch is already part of 'next' as of 7a30cb26 (Merge branch 'jt/object-file-use-container-of' into next, 2026-02-20).
Perhaps a fix-up patch on top of the topic branch like this?
----- >8 ----- Subject: [PATCH] object-file.c: avoid container_of() of a NULL container
Even though the "struct odb_transaction" member is at the beginning of the containing "struct odb_transaction_files", i.e., with offset 0, using container_of() to add offset 0 to a NULL pointer would be flagged as a bad behaviour under SANITIZE=undefined.
Signed-off-by: Junio C Hamano <gitster@pobox.com> --- object-file.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git c/object-file.c w/object-file.c index 1a24f08978..d69cb9b7e2 100644 --- c/object-file.c +++ w/object-file.c @@ -719,8 +719,11 @@ struct odb_transaction_files { static void prepare_loose_object_transaction(struct odb_transaction *base) { - struct odb_transaction_files *transaction = - container_of(base, struct odb_transaction_files, base); + struct odb_transaction_files *transaction = NULL; + + if (base) + transaction = + container_of(base, struct odb_transaction_files, base); /* * We lazily create the temporary object directory @@ -739,8 +742,11 @@ static void prepare_loose_object_transaction(struct odb_transaction *base) static void fsync_loose_object_transaction(struct odb_transaction *base, int fd, const char *filename) { - struct odb_transaction_files *transaction = - container_of(base, struct odb_transaction_files, base); + struct odb_transaction_files *transaction = NULL; + + if (base) + transaction = + container_of(base, struct odb_transaction_files, base); /* * If we have an active ODB transaction, we issue a call that