All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Jonathan Nieder <jrnieder@gmail.com>
Cc: demerphq <demerphq@gmail.com>, Git <git@vger.kernel.org>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: Re: [PATCH 1/7] config: avoid "write_in_full(fd, buf, len) < len" pattern
Date: Wed, 13 Sep 2017 13:53:38 -0400	[thread overview]
Message-ID: <20170913175338.tsq4hmgmmybp43dw@sigill.intra.peff.net> (raw)
In-Reply-To: <20170913174728.GB27425@aiede.mtv.corp.google.com>

On Wed, Sep 13, 2017 at 10:47:28AM -0700, Jonathan Nieder wrote:

> Jeff King wrote:
> 
> > I scoured the code base for cases of this, but it turns out
> > that these two in git_config_set_multivar_in_file_gently()
> > are the only ones. This case is actually quite interesting:
> > we don't have a size_t, but rather use the subtraction of
> > two pointers. Which you might think would be a signed
> > ptrdiff_t, but clearly both gcc and clang treat it as
> > unsigned (possibly because the conditional just above
> > guarantees that the result is greater than zero).
> 
> Do you have more detail about this?  I get worried when I read
> something like this that sounds like a compiler bug.
> 
> C99 sayeth:
> 
> 	When two pointers are subtracted, both shall point to elements
> 	of the same array object, or one past the last element of the
> 	array object; the result is the difference of the subscripts
> 	of the two array elements. The size of the result is
> 	implementation-defined, and its type (a signed integer type)
> 	is ptrdiff_t defined in the <stddef.h> header.

I'm not sure if it's a compiler bug or not. I read the bits about
ptrdiff_t, and it wasn't entirely clear to me if a pointer difference
_is_ an actual ptrdiff_t, or if it can generally be stored in one. Right
below that text it also says:

  If the result is not representable in an object of that type, the
  behavior is undefined.

That said, I might be wrong that unsigned promotion is the culprit. I
didn't look at the generated assembly. But I also can't see what else
would be causing the problem here. We're clearly returning "-1" and the
condition doesn't trigger.

> How can I reproduce the problem?

I gave a recipe in the commit message, which is the best I came up with.
You could probably use a fault-injection library to convince write() to
fail. Or just tweak the source code to have write_in_full() return -1.

> > There's no addition to the test suite here, since you need
> > to convince write() to fail in order to see the problem. The
> > simplest reproduction recipe I came up with is to trigger
> > ENOSPC (this only works on Linux, obviously):
> 
> Does /dev/full make it simpler to reproduce?

I don't think so, because the write() failure is to the lockfile, which
is created with O_EXCL. So even if you could convince "config.lock" to
be the right device type, the open() would fail.

-Peff

  reply	other threads:[~2017-09-13 17:53 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-13 11:59 Bug: git branch --unset-upstream command can nuke config when disk is full demerphq
2017-09-13 12:34 ` Jeff King
2017-09-13 13:38   ` demerphq
2017-09-13 14:17     ` Jeff King
2017-09-13 14:49       ` demerphq
2017-09-13 14:51         ` Jeff King
2017-09-13 15:18           ` demerphq
2017-09-13 15:22             ` Jeff King
2017-09-13 15:49               ` demerphq
2017-09-13 17:08 ` [PATCH 0/7] config.c may fail to notice some write() failures Jeff King
2017-09-13 17:11   ` [PATCH 1/7] config: avoid "write_in_full(fd, buf, len) < len" pattern Jeff King
2017-09-13 17:47     ` Jonathan Nieder
2017-09-13 17:53       ` Jeff King [this message]
2017-09-13 17:59         ` Jonathan Nieder
2017-09-13 18:11           ` Jeff King
2017-09-13 18:15     ` [PATCH v2] " Jeff King
2017-09-13 18:24       ` Jonathan Nieder
2017-09-13 18:58         ` Jeff King
2017-09-13 19:18           ` Jonathan Nieder
2017-09-13 19:49           ` Jonathan Nieder
2017-09-13 22:43           ` Ramsay Jones
2017-09-13 23:31             ` Ramsay Jones
2017-09-15  0:37               ` Jeff King
2017-09-15 15:15                 ` Ramsay Jones
2017-09-13 21:33         ` Junio C Hamano
2017-09-13 17:11   ` [PATCH 2/7] get-tar-commit-id: check write_in_full() return against 0 Jeff King
2017-09-13 17:53     ` Jonathan Nieder
2017-09-13 18:02       ` Jeff King
2017-09-13 18:37         ` Jeff King
2017-09-13 21:09     ` Jonathan Nieder
2017-09-15  0:40       ` Jeff King
2017-09-13 17:16   ` [PATCH 3/7] avoid "write_in_full(fd, buf, len) != len" pattern Jeff King
2017-09-13 21:14     ` Jonathan Nieder
2017-09-15  0:42       ` Jeff King
2017-09-13 17:16   ` [PATCH 4/7] convert less-trivial versions of "write_in_full() != len" Jeff King
2017-09-13 21:16     ` Jonathan Nieder
2017-09-13 17:17   ` [PATCH 5/7] pkt-line: check write_in_full() errors against "< 0" Jeff King
2017-09-13 21:17     ` Jonathan Nieder
2017-09-13 17:17   ` [PATCH 6/7] notes-merge: use ssize_t for write_in_full() return value Jeff King
2017-09-13 21:20     ` Jonathan Nieder
2017-09-15  0:43       ` Jeff King
2017-09-13 17:17   ` [PATCH 7/7] config: flip return value of store_write_*() Jeff King
2017-09-13 21:25     ` Jonathan Nieder
2017-09-15  0:46       ` Jeff King
2017-09-13 18:47   ` [PATCH 8/7] read_pack_header: handle signed/unsigned comparison in read result Jeff King
2017-09-13 19:11     ` Jonathan Nieder

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=20170913175338.tsq4hmgmmybp43dw@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=avarab@gmail.com \
    --cc=demerphq@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jrnieder@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.