git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Phillip Wood <phillip.wood123@gmail.com>
To: Jeff King <peff@peff.net>, Karthik Nayak <karthik.188@gmail.com>
Cc: git@vger.kernel.org, Patrick Steinhardt <ps@pks.im>
Subject: Re: undefined behavior in unit tests, was Re: [PATCH v3 3/3] reftable: prevent 'update_index' changes after adding records
Date: Sat, 1 Feb 2025 10:33:13 +0000	[thread overview]
Message-ID: <425859d1-d42e-42ee-b59c-723a519f0ad8@gmail.com> (raw)
In-Reply-To: <20250201022409.GA4082344@coredump.intra.peff.net>

Hi Peff

On 01/02/2025 02:24, Jeff King wrote:
> On Wed, Jan 22, 2025 at 06:35:49AM +0100, Karthik Nayak wrote:
> 
> Coverity complains that this function may have undefined behavior. It's
> an issue we have in a lot of other tests that have moved to the
> unit-test framework. I've mostly been ignoring it, but this is a pretty
> straight-forward example, so I thought I'd write a note.
> 
> The issue is that reftable_new_stack() might fail, leaving "st" as NULL.
> And then we feed it to reftable_stack_new_addition(), which dereferences
> it.
> 
> In normal production code, we'd expect something like:
> 
>    if (err)
> 	return -1;
> 
> to avoid running the rest of the function after the first error. But the
> test harness check() function doesn't return. It just complains to
> stdout and keeps running! 

That is to allow the test to add more context with test_msg() or do 
things like check all the members of a struct before returning. It is a 
bug in the test if it does not return after finding a NULL pointer, the 
correct usage is

	if (!check(ptr))
		return;

As we're in the process of switching to using clar which does exit the 
text function if a check fails (that means there may be leaks on failure 
but if the test is failing then I don't think we should be worrying 
about leaks) I don't know if it is worth fixing these or not. I guess it 
depends if there are the list of targets for Seyi's Outreachy project.

Best Wishes

Phillip

  So you'll get something like[1]:
> 
>    $ t/unit-tests/bin/t-reftable-stack
>    ok 1 - empty addition to stack
>    ok 2 - read_lines works
>    ok 3 - expire reflog entries
>    # check "!err" failed at t/unit-tests/t-reftable-stack.c:1404
>    Segmentation fault
> 
> So...yes, we will probably notice that the test failed from the exit
> code. But it's not great when the harness itself barfs so had. Plus a
> compiler may be free to reorder things in a confusing way if it can see
> that "st" must never be NULL.
> 
> It feels like we probably ought to return as soon as a check() fails.
> That does create other headaches, though. E.g., we'd potentially leak
> from an early return (which our LSan builds will complain about),
> meaning that test code needs to start doing the usual "goto out" type of
> cleanup.
> 
> So I dunno. Maybe we just live with it. But it feels pretty ugly.
> 
> -Peff
> 
> [1] This would happen in practice if malloc() failed, but you can
>      simulate it yourself like this, which is what I used to create the
>      output above:
> 
> diff --git a/reftable/stack.c b/reftable/stack.c
> index 026a9f9742..fe77132102 100644
> --- a/reftable/stack.c
> +++ b/reftable/stack.c
> @@ -861,6 +861,11 @@ int reftable_stack_new_addition(struct reftable_addition **dest,
>   	int err = 0;
>   	struct reftable_addition empty = REFTABLE_ADDITION_INIT;
>   
> +	if (flags & (1 << 16)) {
> +		*dest = NULL;
> +		return REFTABLE_OUT_OF_MEMORY_ERROR;
> +	}
> +
>   	REFTABLE_CALLOC_ARRAY(*dest, 1);
>   	if (!*dest)
>   		return REFTABLE_OUT_OF_MEMORY_ERROR;
> diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c
> index c3f0059c34..73ed9792a5 100644
> --- a/t/unit-tests/t-reftable-stack.c
> +++ b/t/unit-tests/t-reftable-stack.c
> @@ -1400,7 +1400,7 @@ static void t_reftable_invalid_limit_updates(void)
>   
>   	reftable_addition_destroy(add);
>   
> -	err = reftable_stack_new_addition(&add, st, 0);
> +	err = reftable_stack_new_addition(&add, st, (1 << 16));
>   	check(!err);
>   
>   	/*
> 


  reply	other threads:[~2025-02-01 10:33 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-17  7:59 [PATCH 0/3] refs: small followups to the migration corruption fix Karthik Nayak
2025-01-17  7:59 ` [PATCH 1/3] refs: mark `ref_transaction_update_reflog()` as static Karthik Nayak
2025-01-17  9:29   ` Patrick Steinhardt
2025-01-20 11:17     ` Karthik Nayak
2025-01-17  7:59 ` [PATCH 2/3] refs: use 'uint64_t' for 'ref_update.index' Karthik Nayak
2025-01-17  7:59 ` [PATCH 3/3] reftable: prevent 'update_index' changes after header write Karthik Nayak
2025-01-17  9:29   ` Patrick Steinhardt
2025-01-20 11:47     ` Karthik Nayak
2025-01-20 12:18       ` Karthik Nayak
2025-01-21  3:34 ` [PATCH v2 0/3] refs: small followups to the migration corruption fix Karthik Nayak
2025-01-21  3:34   ` [PATCH v2 1/3] refs: mark `ref_transaction_update_reflog()` as static Karthik Nayak
2025-01-21  3:34   ` [PATCH v2 2/3] refs: use 'uint64_t' for 'ref_update.index' Karthik Nayak
2025-01-21  3:34   ` [PATCH v2 3/3] reftable: prevent 'update_index' changes after adding records Karthik Nayak
2025-01-21  6:56     ` Patrick Steinhardt
2025-01-21 11:44       ` Karthik Nayak
2025-01-22  5:35   ` [PATCH v3 0/3] refs: small followups to the migration corruption fix Karthik Nayak
2025-01-22  5:35     ` [PATCH v3 1/3] refs: mark `ref_transaction_update_reflog()` as static Karthik Nayak
2025-01-22  5:35     ` [PATCH v3 2/3] refs: use 'uint64_t' for 'ref_update.index' Karthik Nayak
2025-01-22  5:35     ` [PATCH v3 3/3] reftable: prevent 'update_index' changes after adding records Karthik Nayak
2025-01-22 12:12       ` Patrick Steinhardt
2025-01-22 17:50         ` Junio C Hamano
2025-01-22 21:57           ` Junio C Hamano
2025-02-01  2:24       ` undefined behavior in unit tests, was " Jeff King
2025-02-01 10:33         ` Phillip Wood [this message]
2025-02-03  5:41           ` Patrick Steinhardt
2025-02-03 14:11             ` Junio C Hamano
2025-02-03 15:37           ` Jeff King
2025-02-03  5:40         ` Patrick Steinhardt
2025-02-03 15:20         ` Karthik Nayak
2025-02-03 15:38           ` Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=425859d1-d42e-42ee-b59c-723a519f0ad8@gmail.com \
    --to=phillip.wood123@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=karthik.188@gmail.com \
    --cc=peff@peff.net \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=ps@pks.im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).