git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* Use of uninitialised value of size 8 in sha1_name.c
@ 2018-02-26  9:04 Christian Couder
  2018-02-26  9:53 ` Jeff King
  0 siblings, 1 reply; 14+ messages in thread
From: Christian Couder @ 2018-02-26  9:04 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: git, Junio C Hamano, Jeff Hostetler, Jonathan Tan

Hi Derrick,

These days when running:

./t5616-partial-clone.sh --valgrind

on master, I get a bunch of:

==21455== Use of uninitialised value of size 8
==21455==    at 0x2D2A73: get_hex_char_from_oid (sha1_name.c:492)
==21455==    by 0x2D2AFE: extend_abbrev_len (sha1_name.c:502)
==21455==    by 0x2D2C3D: find_abbrev_len_for_pack (sha1_name.c:551)
==21455==    by 0x2D2CFF: find_abbrev_len_packed (sha1_name.c:569)
==21455==    by 0x2D2E12: find_unique_abbrev_r (sha1_name.c:608)
==21455==    by 0x2DCB66: strbuf_add_unique_abbrev (strbuf.c:877)
==21455==    by 0x14F7CE: update_local_ref (fetch.c:700)
==21455==    by 0x1500CF: store_updated_refs (fetch.c:871)
==21455==    by 0x15035B: fetch_refs (fetch.c:932)
==21455==    by 0x150CF8: do_fetch (fetch.c:1146)
==21455==    by 0x1515AB: fetch_one (fetch.c:1370)
==21455==    by 0x151A1D: cmd_fetch (fetch.c:1457)
==21455==  Uninitialised value was created by a stack allocation
==21455==    at 0x2D2B2E: find_abbrev_len_for_pack (sha1_name.c:513)
==21455==

A quick git blame seems to point to 0e87b85683 (sha1_name: minimize
OID comparisons during disambiguation, 2017-10-12).

It is difficult to tell for sure though as t5616-partial-clone.sh was
added after that commit.

Best,
Christian.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Use of uninitialised value of size 8 in sha1_name.c
  2018-02-26  9:04 Use of uninitialised value of size 8 in sha1_name.c Christian Couder
@ 2018-02-26  9:53 ` Jeff King
  2018-02-26 10:23   ` Christian Couder
  0 siblings, 1 reply; 14+ messages in thread
From: Jeff King @ 2018-02-26  9:53 UTC (permalink / raw)
  To: Christian Couder
  Cc: Derrick Stolee, git, Junio C Hamano, Jeff Hostetler, Jonathan Tan

On Mon, Feb 26, 2018 at 10:04:22AM +0100, Christian Couder wrote:

> ==21455== Use of uninitialised value of size 8
> ==21455==    at 0x2D2A73: get_hex_char_from_oid (sha1_name.c:492)
> ==21455==    by 0x2D2AFE: extend_abbrev_len (sha1_name.c:502)
> ==21455==    by 0x2D2C3D: find_abbrev_len_for_pack (sha1_name.c:551)
> ==21455==    by 0x2D2CFF: find_abbrev_len_packed (sha1_name.c:569)
> ==21455==    by 0x2D2E12: find_unique_abbrev_r (sha1_name.c:608)
> ==21455==    by 0x2DCB66: strbuf_add_unique_abbrev (strbuf.c:877)
> ==21455==    by 0x14F7CE: update_local_ref (fetch.c:700)
> ==21455==    by 0x1500CF: store_updated_refs (fetch.c:871)
> ==21455==    by 0x15035B: fetch_refs (fetch.c:932)
> ==21455==    by 0x150CF8: do_fetch (fetch.c:1146)
> ==21455==    by 0x1515AB: fetch_one (fetch.c:1370)
> ==21455==    by 0x151A1D: cmd_fetch (fetch.c:1457)
> ==21455==  Uninitialised value was created by a stack allocation
> ==21455==    at 0x2D2B2E: find_abbrev_len_for_pack (sha1_name.c:513)
> ==21455==
> 
> A quick git blame seems to point to 0e87b85683 (sha1_name: minimize
> OID comparisons during disambiguation, 2017-10-12).
> 
> It is difficult to tell for sure though as t5616-partial-clone.sh was
> added after that commit.

I think that commit is to blame, though the error isn't exactly where
that stack trace puts it. Try this:

diff --git a/sha1_name.c b/sha1_name.c
index 611c7d24dd..6f7f36436f 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -547,7 +547,10 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
 	 */
 	mad->init_len = 0;
 	if (!match) {
-		nth_packed_object_oid(&oid, p, first);
+		warning("p->num_objects = %u, first = %u",
+			p->num_objects, first);
+		if (!nth_packed_object_oid(&oid, p, first))
+			die("oops!");
 		extend_abbrev_len(&oid, mad);
 	} else if (first < num - 1) {
 		nth_packed_object_oid(&oid, p, first + 1);

I get failures all over the test suite, like this:

  warning: p->num_objects = 4, first = 3
  warning: p->num_objects = 8, first = 6
  warning: p->num_objects = 10, first = 0
  warning: p->num_objects = 4, first = 0
  warning: p->num_objects = 8, first = 0
  warning: p->num_objects = 10, first = 10
  fatal: oops!

Any time the abbreviated hex would go after the last object in the pack,
then first==p->num_objects, and nth_packed_object_oid() will fail. That
leaves uninitialized data in "oid", which is what valgrind complains
about when we examine it in extend_abbrev_len().

Most of the time the code behaves correctly anyway, because the
uninitialized bytes are unlikely to match up with our hex and extend the
length. Probably we just need to detect that case and skip the call to
extend_abbrev_len() altogether.

-Peff

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: Use of uninitialised value of size 8 in sha1_name.c
  2018-02-26  9:53 ` Jeff King
@ 2018-02-26 10:23   ` Christian Couder
  2018-02-26 14:06     ` Derrick Stolee
  0 siblings, 1 reply; 14+ messages in thread
From: Christian Couder @ 2018-02-26 10:23 UTC (permalink / raw)
  To: Jeff King
  Cc: Derrick Stolee, git, Junio C Hamano, Jeff Hostetler, Jonathan Tan

On Mon, Feb 26, 2018 at 10:53 AM, Jeff King <peff@peff.net> wrote:
> On Mon, Feb 26, 2018 at 10:04:22AM +0100, Christian Couder wrote:
>
>> ==21455== Use of uninitialised value of size 8
>> ==21455==    at 0x2D2A73: get_hex_char_from_oid (sha1_name.c:492)
>> ==21455==    by 0x2D2AFE: extend_abbrev_len (sha1_name.c:502)
>> ==21455==    by 0x2D2C3D: find_abbrev_len_for_pack (sha1_name.c:551)
>> ==21455==    by 0x2D2CFF: find_abbrev_len_packed (sha1_name.c:569)
>> ==21455==    by 0x2D2E12: find_unique_abbrev_r (sha1_name.c:608)
>> ==21455==    by 0x2DCB66: strbuf_add_unique_abbrev (strbuf.c:877)
>> ==21455==    by 0x14F7CE: update_local_ref (fetch.c:700)
>> ==21455==    by 0x1500CF: store_updated_refs (fetch.c:871)
>> ==21455==    by 0x15035B: fetch_refs (fetch.c:932)
>> ==21455==    by 0x150CF8: do_fetch (fetch.c:1146)
>> ==21455==    by 0x1515AB: fetch_one (fetch.c:1370)
>> ==21455==    by 0x151A1D: cmd_fetch (fetch.c:1457)
>> ==21455==  Uninitialised value was created by a stack allocation
>> ==21455==    at 0x2D2B2E: find_abbrev_len_for_pack (sha1_name.c:513)
>> ==21455==
>>
>> A quick git blame seems to point to 0e87b85683 (sha1_name: minimize
>> OID comparisons during disambiguation, 2017-10-12).
>>
>> It is difficult to tell for sure though as t5616-partial-clone.sh was
>> added after that commit.
>
> I think that commit is to blame, though the error isn't exactly where
> that stack trace puts it. Try this:
>
> diff --git a/sha1_name.c b/sha1_name.c
> index 611c7d24dd..6f7f36436f 100644
> --- a/sha1_name.c
> +++ b/sha1_name.c
> @@ -547,7 +547,10 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
>          */
>         mad->init_len = 0;
>         if (!match) {
> -               nth_packed_object_oid(&oid, p, first);
> +               warning("p->num_objects = %u, first = %u",
> +                       p->num_objects, first);
> +               if (!nth_packed_object_oid(&oid, p, first))
> +                       die("oops!");
>                 extend_abbrev_len(&oid, mad);
>         } else if (first < num - 1) {
>                 nth_packed_object_oid(&oid, p, first + 1);
>
> I get failures all over the test suite, like this:
>
>   warning: p->num_objects = 4, first = 3
>   warning: p->num_objects = 8, first = 6
>   warning: p->num_objects = 10, first = 0
>   warning: p->num_objects = 4, first = 0
>   warning: p->num_objects = 8, first = 0
>   warning: p->num_objects = 10, first = 10
>   fatal: oops!

Yeah, I tried to t5601-clone.sh with --valgrind and I also get one
error (the same "Uninitialised value" error actually).

> Any time the abbreviated hex would go after the last object in the pack,
> then first==p->num_objects, and nth_packed_object_oid() will fail. That
> leaves uninitialized data in "oid", which is what valgrind complains
> about when we examine it in extend_abbrev_len().
>
> Most of the time the code behaves correctly anyway, because the
> uninitialized bytes are unlikely to match up with our hex and extend the
> length. Probably we just need to detect that case and skip the call to
> extend_abbrev_len() altogether.

Yeah, something like:

diff --git a/sha1_name.c b/sha1_name.c
index 611c7d24dd..a041d8d24f 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -547,15 +547,15 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
         */
        mad->init_len = 0;
        if (!match) {
-               nth_packed_object_oid(&oid, p, first);
-               extend_abbrev_len(&oid, mad);
+               if (nth_packed_object_oid(&oid, p, first))
+                       extend_abbrev_len(&oid, mad);
        } else if (first < num - 1) {
-               nth_packed_object_oid(&oid, p, first + 1);
-               extend_abbrev_len(&oid, mad);
+               if (nth_packed_object_oid(&oid, p, first + 1))
+                       extend_abbrev_len(&oid, mad);
        }
        if (first > 0) {
-               nth_packed_object_oid(&oid, p, first - 1);
-               extend_abbrev_len(&oid, mad);
+               if (nth_packed_object_oid(&oid, p, first - 1))
+                       extend_abbrev_len(&oid, mad);
        }
        mad->init_len = mad->cur_len;
 }

seems to prevent valgrind from complaining when running t5616-partial-clone.sh.

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: Use of uninitialised value of size 8 in sha1_name.c
  2018-02-26 10:23   ` Christian Couder
@ 2018-02-26 14:06     ` Derrick Stolee
  2018-02-26 14:43       ` Christian Couder
  0 siblings, 1 reply; 14+ messages in thread
From: Derrick Stolee @ 2018-02-26 14:06 UTC (permalink / raw)
  To: Christian Couder, Jeff King
  Cc: git, Junio C Hamano, Jeff Hostetler, Jonathan Tan, dstolee

On 2/26/2018 5:23 AM, Christian Couder wrote:
> On Mon, Feb 26, 2018 at 10:53 AM, Jeff King <peff@peff.net> wrote:
>> On Mon, Feb 26, 2018 at 10:04:22AM +0100, Christian Couder wrote:
>>
>>> ==21455== Use of uninitialised value of size 8
>>> ==21455==    at 0x2D2A73: get_hex_char_from_oid (sha1_name.c:492)
>>> ==21455==    by 0x2D2AFE: extend_abbrev_len (sha1_name.c:502)
>>> ==21455==    by 0x2D2C3D: find_abbrev_len_for_pack (sha1_name.c:551)
>>> ==21455==    by 0x2D2CFF: find_abbrev_len_packed (sha1_name.c:569)
>>> ==21455==    by 0x2D2E12: find_unique_abbrev_r (sha1_name.c:608)
>>> ==21455==    by 0x2DCB66: strbuf_add_unique_abbrev (strbuf.c:877)
>>> ==21455==    by 0x14F7CE: update_local_ref (fetch.c:700)
>>> ==21455==    by 0x1500CF: store_updated_refs (fetch.c:871)
>>> ==21455==    by 0x15035B: fetch_refs (fetch.c:932)
>>> ==21455==    by 0x150CF8: do_fetch (fetch.c:1146)
>>> ==21455==    by 0x1515AB: fetch_one (fetch.c:1370)
>>> ==21455==    by 0x151A1D: cmd_fetch (fetch.c:1457)
>>> ==21455==  Uninitialised value was created by a stack allocation
>>> ==21455==    at 0x2D2B2E: find_abbrev_len_for_pack (sha1_name.c:513)
>>> ==21455==
>>>
>>> A quick git blame seems to point to 0e87b85683 (sha1_name: minimize
>>> OID comparisons during disambiguation, 2017-10-12).
>>>
>>> It is difficult to tell for sure though as t5616-partial-clone.sh was
>>> added after that commit.
>> I think that commit is to blame, though the error isn't exactly where
>> that stack trace puts it. Try this:
>>
>> diff --git a/sha1_name.c b/sha1_name.c
>> index 611c7d24dd..6f7f36436f 100644
>> --- a/sha1_name.c
>> +++ b/sha1_name.c
>> @@ -547,7 +547,10 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
>>           */
>>          mad->init_len = 0;
>>          if (!match) {
>> -               nth_packed_object_oid(&oid, p, first);
>> +               warning("p->num_objects = %u, first = %u",
>> +                       p->num_objects, first);
>> +               if (!nth_packed_object_oid(&oid, p, first))
>> +                       die("oops!");
>>                  extend_abbrev_len(&oid, mad);
>>          } else if (first < num - 1) {
>>                  nth_packed_object_oid(&oid, p, first + 1);
>>
>> I get failures all over the test suite, like this:
>>
>>    warning: p->num_objects = 4, first = 3
>>    warning: p->num_objects = 8, first = 6
>>    warning: p->num_objects = 10, first = 0
>>    warning: p->num_objects = 4, first = 0
>>    warning: p->num_objects = 8, first = 0
>>    warning: p->num_objects = 10, first = 10
>>    fatal: oops!
> Yeah, I tried to t5601-clone.sh with --valgrind and I also get one
> error (the same "Uninitialised value" error actually).

Thanks for finding this. Sorry for the bug.

>> Any time the abbreviated hex would go after the last object in the pack,
>> then first==p->num_objects, and nth_packed_object_oid() will fail. That
>> leaves uninitialized data in "oid", which is what valgrind complains
>> about when we examine it in extend_abbrev_len().
>>
>> Most of the time the code behaves correctly anyway, because the
>> uninitialized bytes are unlikely to match up with our hex and extend the
>> length. Probably we just need to detect that case and skip the call to
>> extend_abbrev_len() altogether.
> Yeah, something like:
>
> diff --git a/sha1_name.c b/sha1_name.c
> index 611c7d24dd..a041d8d24f 100644
> --- a/sha1_name.c
> +++ b/sha1_name.c
> @@ -547,15 +547,15 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
>           */
>          mad->init_len = 0;
>          if (!match) {
> -               nth_packed_object_oid(&oid, p, first);
> -               extend_abbrev_len(&oid, mad);
> +               if (nth_packed_object_oid(&oid, p, first))
> +                       extend_abbrev_len(&oid, mad);
>          } else if (first < num - 1) {
> -               nth_packed_object_oid(&oid, p, first + 1);
> -               extend_abbrev_len(&oid, mad);
> +               if (nth_packed_object_oid(&oid, p, first + 1))
> +                       extend_abbrev_len(&oid, mad);
>          }
>          if (first > 0) {
> -               nth_packed_object_oid(&oid, p, first - 1);
> -               extend_abbrev_len(&oid, mad);
> +               if (nth_packed_object_oid(&oid, p, first - 1))
> +                       extend_abbrev_len(&oid, mad);
>          }
>          mad->init_len = mad->cur_len;
>   }
>
> seems to prevent valgrind from complaining when running t5616-partial-clone.sh.

This seems like the safest fix, but also we could use our values of 
"match", "first" and "num" to safely call nth_packed_object_oid(). 
However, since nth_packed_object_oid() checks the bounds, don't 
duplicate work and just use the return value.

I would reformat your patch slightly, but that's just preference:

diff --git a/sha1_name.c b/sha1_name.c
index 611c7d2..97b632c 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -546,17 +546,14 @@ static void find_abbrev_len_for_pack(struct 
packed_git *p,
          * nearby for the abbreviation length.
          */
         mad->init_len = 0;
-       if (!match) {
-               nth_packed_object_oid(&oid, p, first);
+       if (!match && nth_packed_object_oid(&oid, p, first))
                 extend_abbrev_len(&oid, mad);
-       } else if (first < num - 1) {
-               nth_packed_object_oid(&oid, p, first + 1);
+       else if (first < num - 1 &&
+                nth_packed_object_oid(&oid, p, first + 1))
                 extend_abbrev_len(&oid, mad);
-       }
-       if (first > 0) {
-               nth_packed_object_oid(&oid, p, first - 1);
+       if (first > 0 && nth_packed_object_oid(&oid, p, first - 1))
                 extend_abbrev_len(&oid, mad);
-       }
+
         mad->init_len = mad->cur_len;
  }

Christian: do you want to submit the patch, or should I put one together?

Thanks,
-Stolee


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: Use of uninitialised value of size 8 in sha1_name.c
  2018-02-26 14:06     ` Derrick Stolee
@ 2018-02-26 14:43       ` Christian Couder
  2018-02-26 14:56         ` [PATCH] sha1_name: fix uninitialized memory errors Derrick Stolee
  0 siblings, 1 reply; 14+ messages in thread
From: Christian Couder @ 2018-02-26 14:43 UTC (permalink / raw)
  To: Derrick Stolee
  Cc: Jeff King, git, Junio C Hamano, Jeff Hostetler, Jonathan Tan,
	dstolee

On Mon, Feb 26, 2018 at 3:06 PM, Derrick Stolee <stolee@gmail.com> wrote:
>
> Christian: do you want to submit the patch, or should I put one together?

I'd rather have you put one together.

Thanks,
Christian.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH] sha1_name: fix uninitialized memory errors
  2018-02-26 14:43       ` Christian Couder
@ 2018-02-26 14:56         ` Derrick Stolee
  2018-02-26 20:41           ` Jeff King
  0 siblings, 1 reply; 14+ messages in thread
From: Derrick Stolee @ 2018-02-26 14:56 UTC (permalink / raw)
  To: git; +Cc: christian.couder, peff, stolee, Derrick Stolee

During abbreviation checks, we navigate to the position within a
pack-index that an OID would be inserted and check surrounding OIDs
for the maximum matching prefix. This position may be beyond the
last position, because the given OID is lexicographically larger
than every OID in the pack. Then nth_packed_object_oid() does not
initialize "oid".

Use the return value of nth_packed_object_oid() to prevent these
errors.

Reported-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
 sha1_name.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 611c7d2..44dd595 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -546,17 +546,12 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
 	 * nearby for the abbreviation length.
 	 */
 	mad->init_len = 0;
-	if (!match) {
-		nth_packed_object_oid(&oid, p, first);
+	if (!match && nth_packed_object_oid(&oid, p, first))
 		extend_abbrev_len(&oid, mad);
-	} else if (first < num - 1) {
-		nth_packed_object_oid(&oid, p, first + 1);
+	else if (first < num - 1 && nth_packed_object_oid(&oid, p, first + 1))
 		extend_abbrev_len(&oid, mad);
-	}
-	if (first > 0) {
-		nth_packed_object_oid(&oid, p, first - 1);
+	if (first > 0 && nth_packed_object_oid(&oid, p, first - 1))
 		extend_abbrev_len(&oid, mad);
-	}
 	mad->init_len = mad->cur_len;
 }
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] sha1_name: fix uninitialized memory errors
  2018-02-26 14:56         ` [PATCH] sha1_name: fix uninitialized memory errors Derrick Stolee
@ 2018-02-26 20:41           ` Jeff King
  2018-02-27 11:47             ` [PATCH v2] " Derrick Stolee
  0 siblings, 1 reply; 14+ messages in thread
From: Jeff King @ 2018-02-26 20:41 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: git, christian.couder, stolee

On Mon, Feb 26, 2018 at 09:56:47AM -0500, Derrick Stolee wrote:

> diff --git a/sha1_name.c b/sha1_name.c
> index 611c7d2..44dd595 100644
> --- a/sha1_name.c
> +++ b/sha1_name.c
> @@ -546,17 +546,12 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
>  	 * nearby for the abbreviation length.
>  	 */
>  	mad->init_len = 0;
> -	if (!match) {
> -		nth_packed_object_oid(&oid, p, first);
> +	if (!match && nth_packed_object_oid(&oid, p, first))
>  		extend_abbrev_len(&oid, mad);
> -	} else if (first < num - 1) {
> -		nth_packed_object_oid(&oid, p, first + 1);
> +	else if (first < num - 1 && nth_packed_object_oid(&oid, p, first + 1))
>  		extend_abbrev_len(&oid, mad);
> -	}

I think including the nth_packed_object_oid() in the main if-else chain
works out, but it's kind of tricky.

In the code before, we'd hit the "first < num - 1" conditional only when
we didn't match something. But now we also hit it if we _did_ match
something, but nth_packed_object_oid() didn't work.

But this works out the same if we assume any match must also succeed at
nth_packed_object_oid(). Which in turn implies that checking the result
of nth_packed_object_oid() in the "else if" is redundant (though we
already clamp it to "num - 1", so we'd expect it to always succeed
anyway).

So I think this behaves well, but I wonder if the two-level conditionals
like:

  if (!match) {
	if (nth_packed_object_oid(&oid, p, first))
		extend_abbrev_len(&oid, mad);
  } else if ...

are easier to reason about.

-Peff

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2] sha1_name: fix uninitialized memory errors
  2018-02-26 20:41           ` Jeff King
@ 2018-02-27 11:47             ` Derrick Stolee
  2018-02-27 21:33               ` Jeff King
  2018-02-28 20:50               ` Junio C Hamano
  0 siblings, 2 replies; 14+ messages in thread
From: Derrick Stolee @ 2018-02-27 11:47 UTC (permalink / raw)
  To: git; +Cc: peff, stolee, christian.couder, Derrick Stolee

Peff made an excellent point about the nested if statements. This
goes back to Christian's original recommendation.

-- >8 --

During abbreviation checks, we navigate to the position within a
pack-index that an OID would be inserted and check surrounding OIDs
for the maximum matching prefix. This position may be beyond the
last position, because the given OID is lexicographically larger
than every OID in the pack. Then nth_packed_object_oid() does not
initialize "oid".

Use the return value of nth_packed_object_oid() to prevent these
errors.

Reported-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
 sha1_name.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 611c7d24dd..a041d8d24f 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -547,15 +547,15 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
 	 */
 	mad->init_len = 0;
 	if (!match) {
-		nth_packed_object_oid(&oid, p, first);
-		extend_abbrev_len(&oid, mad);
+		if (nth_packed_object_oid(&oid, p, first))
+			extend_abbrev_len(&oid, mad);
 	} else if (first < num - 1) {
-		nth_packed_object_oid(&oid, p, first + 1);
-		extend_abbrev_len(&oid, mad);
+		if (nth_packed_object_oid(&oid, p, first + 1))
+			extend_abbrev_len(&oid, mad);
 	}
 	if (first > 0) {
-		nth_packed_object_oid(&oid, p, first - 1);
-		extend_abbrev_len(&oid, mad);
+		if (nth_packed_object_oid(&oid, p, first - 1))
+			extend_abbrev_len(&oid, mad);
 	}
 	mad->init_len = mad->cur_len;
 }
-- 
2.16.2.265.g3d5930c0b9.dirty


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] sha1_name: fix uninitialized memory errors
  2018-02-27 11:47             ` [PATCH v2] " Derrick Stolee
@ 2018-02-27 21:33               ` Jeff King
  2018-02-27 22:30                 ` Junio C Hamano
  2018-02-28 20:50               ` Junio C Hamano
  1 sibling, 1 reply; 14+ messages in thread
From: Jeff King @ 2018-02-27 21:33 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: git, stolee, christian.couder

On Tue, Feb 27, 2018 at 06:47:04AM -0500, Derrick Stolee wrote:

> Peff made an excellent point about the nested if statements. This
> goes back to Christian's original recommendation.
> 
> -- >8 --
> 
> During abbreviation checks, we navigate to the position within a
> pack-index that an OID would be inserted and check surrounding OIDs
> for the maximum matching prefix. This position may be beyond the
> last position, because the given OID is lexicographically larger
> than every OID in the pack. Then nth_packed_object_oid() does not
> initialize "oid".
> 
> Use the return value of nth_packed_object_oid() to prevent these
> errors.
> 
> Reported-by: Christian Couder <christian.couder@gmail.com>
> Signed-off-by: Derrick Stolee <dstolee@microsoft.com>

Thanks, this looks good to me.

Semi-related, I wondered also at the weird asymmetry in the if-else,
which is:

  if ...
  else if ...
  if ...

but the comment directly above says: "we consider a maximum of three
objects nearby". I think it's actually two, because you can only trigger
one of the first two conditionals.

Is that right?

Let's imagine we're looking for object 1234abcd.  If we didn't find a
match, then we might have:

  1234abcc 
  1234abce <-- first points here

in which case we need to check both first-1 and first. And we do.

If we do have a match, then we might see:

  1234abcc
  1234abcd <-- first points here
  1234abce

and we must check first-1 and first+1, but _not_ first.

So I think the code is right, but the comment is wrong.

-Peff

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] sha1_name: fix uninitialized memory errors
  2018-02-27 21:33               ` Jeff King
@ 2018-02-27 22:30                 ` Junio C Hamano
  2018-02-27 22:40                   ` Jeff King
  0 siblings, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2018-02-27 22:30 UTC (permalink / raw)
  To: Jeff King; +Cc: Derrick Stolee, git, stolee, christian.couder

Jeff King <peff@peff.net> writes:

> Thanks, this looks good to me.
>
> Semi-related, I wondered also at the weird asymmetry in the if-else,
> ...
> So I think the code is right, but the comment is wrong.



-- >8 --
From: Derrick Stolee <dstolee@microsoft.com>
Date: Tue, 27 Feb 2018 06:47:04 -0500
Subject: [PATCH] sha1_name: fix uninitialized memory errors

During abbreviation checks, we navigate to the position within a
pack-index that an OID would be inserted and check surrounding OIDs
for the maximum matching prefix. This position may be beyond the
last position, because the given OID is lexicographically larger
than every OID in the pack. Then nth_packed_object_oid() does not
initialize "oid".

Use the return value of nth_packed_object_oid() to prevent these
errors.

Also the comment about checking near-by objects miscounts the
neighbours.  If we have a hit at "first", we check "first-1" and
"first+1" to make sure we have sufficiently long abbreviation not to
match either.  If we do not have a hit, "first" is the smallest
among the objects that are larger than what we want to name, so we
check that and "first-1" to make sure we have sufficiently long
abbreviation not to match either.  In either case, we only check up
to two near-by objects.

Reported-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 05a635911b..f1c3d37a6d 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -542,20 +542,20 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
 	/*
 	 * first is now the position in the packfile where we would insert
 	 * mad->hash if it does not exist (or the position of mad->hash if
-	 * it does exist). Hence, we consider a maximum of three objects
+	 * it does exist). Hence, we consider a maximum of two objects
 	 * nearby for the abbreviation length.
 	 */
 	mad->init_len = 0;
 	if (!match) {
-		nth_packed_object_oid(&oid, p, first);
-		extend_abbrev_len(&oid, mad);
+		if (nth_packed_object_oid(&oid, p, first))
+			extend_abbrev_len(&oid, mad);
 	} else if (first < num - 1) {
-		nth_packed_object_oid(&oid, p, first + 1);
-		extend_abbrev_len(&oid, mad);
+		if (nth_packed_object_oid(&oid, p, first + 1))
+			extend_abbrev_len(&oid, mad);
 	}
 	if (first > 0) {
-		nth_packed_object_oid(&oid, p, first - 1);
-		extend_abbrev_len(&oid, mad);
+		if (nth_packed_object_oid(&oid, p, first - 1))
+			extend_abbrev_len(&oid, mad);
 	}
 	mad->init_len = mad->cur_len;
 }
-- 
2.16.2-325-g2fc74f41c5


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] sha1_name: fix uninitialized memory errors
  2018-02-27 22:30                 ` Junio C Hamano
@ 2018-02-27 22:40                   ` Jeff King
  0 siblings, 0 replies; 14+ messages in thread
From: Jeff King @ 2018-02-27 22:40 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Derrick Stolee, git, stolee, christian.couder

On Tue, Feb 27, 2018 at 02:30:39PM -0800, Junio C Hamano wrote:

> -- >8 --
> From: Derrick Stolee <dstolee@microsoft.com>
> Date: Tue, 27 Feb 2018 06:47:04 -0500
> Subject: [PATCH] sha1_name: fix uninitialized memory errors
> 
> During abbreviation checks, we navigate to the position within a
> pack-index that an OID would be inserted and check surrounding OIDs
> for the maximum matching prefix. This position may be beyond the
> last position, because the given OID is lexicographically larger
> than every OID in the pack. Then nth_packed_object_oid() does not
> initialize "oid".
> 
> Use the return value of nth_packed_object_oid() to prevent these
> errors.
> 
> Also the comment about checking near-by objects miscounts the
> neighbours.  If we have a hit at "first", we check "first-1" and
> "first+1" to make sure we have sufficiently long abbreviation not to
> match either.  If we do not have a hit, "first" is the smallest
> among the objects that are larger than what we want to name, so we
> check that and "first-1" to make sure we have sufficiently long
> abbreviation not to match either.  In either case, we only check up
> to two near-by objects.

Yep, this looks good to me. Thanks for wrapping it up.

-Peff

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] sha1_name: fix uninitialized memory errors
  2018-02-27 11:47             ` [PATCH v2] " Derrick Stolee
  2018-02-27 21:33               ` Jeff King
@ 2018-02-28 20:50               ` Junio C Hamano
  2018-02-28 20:57                 ` Derrick Stolee
  1 sibling, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2018-02-28 20:50 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: git, peff, stolee, christian.couder

Derrick Stolee <dstolee@microsoft.com> writes:

> diff --git a/sha1_name.c b/sha1_name.c
> index 611c7d24dd..a041d8d24f 100644
> --- a/sha1_name.c
> +++ b/sha1_name.c
> @@ -547,15 +547,15 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
>  	 */
>  	mad->init_len = 0;
>  	if (!match) {
> -		nth_packed_object_oid(&oid, p, first);
> -		extend_abbrev_len(&oid, mad);
> +		if (nth_packed_object_oid(&oid, p, first))
> +			extend_abbrev_len(&oid, mad);
>  	} else if (first < num - 1) {
> -		nth_packed_object_oid(&oid, p, first + 1);
> -		extend_abbrev_len(&oid, mad);
> +		if (nth_packed_object_oid(&oid, p, first + 1))
> +			extend_abbrev_len(&oid, mad);
>  	}
>  	if (first > 0) {
> -		nth_packed_object_oid(&oid, p, first - 1);
> -		extend_abbrev_len(&oid, mad);
> +		if (nth_packed_object_oid(&oid, p, first - 1))
> +			extend_abbrev_len(&oid, mad);
>  	}
>  	mad->init_len = mad->cur_len;
>  }

I do not think they are wrong, but aren't the latter two somewhat
redundant?  "num" is p->num_objects, and we call (first+1)th element
only after we see (first < num - 1), i.e. first+1 < num, and the
access to (first-1)th is done only when first > 0.  The first one,
i.e. when first points at where we _would_ find it if it existed,
can access "first" that could be p->num_objects, so the change there
makes sense, though.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] sha1_name: fix uninitialized memory errors
  2018-02-28 20:50               ` Junio C Hamano
@ 2018-02-28 20:57                 ` Derrick Stolee
  2018-02-28 21:06                   ` Junio C Hamano
  0 siblings, 1 reply; 14+ messages in thread
From: Derrick Stolee @ 2018-02-28 20:57 UTC (permalink / raw)
  To: Junio C Hamano, Derrick Stolee; +Cc: git, peff, christian.couder

On 2/28/2018 3:50 PM, Junio C Hamano wrote:
> Derrick Stolee <dstolee@microsoft.com> writes:
>
>> diff --git a/sha1_name.c b/sha1_name.c
>> index 611c7d24dd..a041d8d24f 100644
>> --- a/sha1_name.c
>> +++ b/sha1_name.c
>> @@ -547,15 +547,15 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
>>   	 */
>>   	mad->init_len = 0;
>>   	if (!match) {
>> -		nth_packed_object_oid(&oid, p, first);
>> -		extend_abbrev_len(&oid, mad);
>> +		if (nth_packed_object_oid(&oid, p, first))
>> +			extend_abbrev_len(&oid, mad);
>>   	} else if (first < num - 1) {
>> -		nth_packed_object_oid(&oid, p, first + 1);
>> -		extend_abbrev_len(&oid, mad);
>> +		if (nth_packed_object_oid(&oid, p, first + 1))
>> +			extend_abbrev_len(&oid, mad);
>>   	}
>>   	if (first > 0) {
>> -		nth_packed_object_oid(&oid, p, first - 1);
>> -		extend_abbrev_len(&oid, mad);
>> +		if (nth_packed_object_oid(&oid, p, first - 1))
>> +			extend_abbrev_len(&oid, mad);
>>   	}
>>   	mad->init_len = mad->cur_len;
>>   }
> I do not think they are wrong, but aren't the latter two somewhat
> redundant?  "num" is p->num_objects, and we call (first+1)th element
> only after we see (first < num - 1), i.e. first+1 < num, and the
> access to (first-1)th is done only when first > 0.  The first one,
> i.e. when first points at where we _would_ find it if it existed,
> can access "first" that could be p->num_objects, so the change there
> makes sense, though.
>

Yes. But I'd rather keep the blocks consistent and use the return value 
of nth_packed_object_oid() when possible.

Thanks,
-Stolee

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] sha1_name: fix uninitialized memory errors
  2018-02-28 20:57                 ` Derrick Stolee
@ 2018-02-28 21:06                   ` Junio C Hamano
  0 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2018-02-28 21:06 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: Derrick Stolee, git, peff, christian.couder

Derrick Stolee <stolee@gmail.com> writes:

>> I do not think they are wrong, but aren't the latter two somewhat
>> redundant?  "num" is p->num_objects, and we call (first+1)th element
>> only after we see (first < num - 1), i.e. first+1 < num, and the
>> access to (first-1)th is done only when first > 0.  The first one,
>> i.e. when first points at where we _would_ find it if it existed,
>> can access "first" that could be p->num_objects, so the change there
>> makes sense, though.
>
> Yes. But I'd rather keep the blocks consistent and use the return
> value of nth_packed_object_oid() when possible.

Sure, I do not think anybody minds; I just wanted a sanity check.

Thansk.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2018-02-28 21:06 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-26  9:04 Use of uninitialised value of size 8 in sha1_name.c Christian Couder
2018-02-26  9:53 ` Jeff King
2018-02-26 10:23   ` Christian Couder
2018-02-26 14:06     ` Derrick Stolee
2018-02-26 14:43       ` Christian Couder
2018-02-26 14:56         ` [PATCH] sha1_name: fix uninitialized memory errors Derrick Stolee
2018-02-26 20:41           ` Jeff King
2018-02-27 11:47             ` [PATCH v2] " Derrick Stolee
2018-02-27 21:33               ` Jeff King
2018-02-27 22:30                 ` Junio C Hamano
2018-02-27 22:40                   ` Jeff King
2018-02-28 20:50               ` Junio C Hamano
2018-02-28 20:57                 ` Derrick Stolee
2018-02-28 21:06                   ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).