<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/packfile.c, branch v2.37.4</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/git/git.git/
</subtitle>
<id>https://git.shady.money/git/atom?h=v2.37.4</id>
<link rel='self' href='https://git.shady.money/git/atom?h=v2.37.4'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/'/>
<updated>2022-09-13T19:21:07Z</updated>
<entry>
<title>Merge branch 'jk/is-promisor-object-keep-tree-in-use' into maint</title>
<updated>2022-09-13T19:21:07Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2022-09-13T19:21:07Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=72869e750bf62fa313e7854d18e48c083f4720cc'/>
<id>urn:sha1:72869e750bf62fa313e7854d18e48c083f4720cc</id>
<content type='text'>
An earlier optimization discarded a tree-object buffer that is
still in use, which has been corrected.

* jk/is-promisor-object-keep-tree-in-use:
  is_promisor_object(): fix use-after-free of tree buffer
</content>
</entry>
<entry>
<title>is_promisor_object(): fix use-after-free of tree buffer</title>
<updated>2022-08-15T01:03:36Z</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2022-08-14T06:29:15Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=1490d7d82d5bd504b095c4db030a98b8080c596a'/>
<id>urn:sha1:1490d7d82d5bd504b095c4db030a98b8080c596a</id>
<content type='text'>
Since commit fcc07e980b (is_promisor_object(): free tree buffer after
parsing, 2021-04-13), we'll always free the buffers attached to a
"struct tree" after searching them for promisor links. But there's an
important case where we don't want to do so: if somebody else is already
using the tree!

This can happen during a "rev-list --missing=allow-promisor" traversal
in a partial clone that is missing one or more trees or blobs. The
backtrace for the free looks like this:

      #1 free_tree_buffer tree.c:147
      #2 add_promisor_object packfile.c:2250
      #3 for_each_object_in_pack packfile.c:2190
      #4 for_each_packed_object packfile.c:2215
      #5 is_promisor_object packfile.c:2272
      #6 finish_object__ma builtin/rev-list.c:245
      #7 finish_object builtin/rev-list.c:261
      #8 show_object builtin/rev-list.c:274
      #9 process_blob list-objects.c:63
      #10 process_tree_contents list-objects.c:145
      #11 process_tree list-objects.c:201
      #12 traverse_trees_and_blobs list-objects.c:344
      [...]

We're in the middle of walking through the entries of a tree object via
process_tree_contents(). We see a blob (or it could even be another tree
entry) that we don't have, so we call is_promisor_object() to check it.
That function loops over all of the objects in the promisor packfile,
including the tree we're currently walking. When we're done with it
there, we free the tree buffer. But as we return to the walk in
process_tree_contents(), it's still holding on to a pointer to that
buffer, via its tree_desc iterator, and it accesses the freed memory.

Even a trivial use of "--missing=allow-promisor" triggers this problem,
as the included test demonstrates (it's just a vanilla --blob:none
clone).

We can detect this case by only freeing the tree buffer if it was
allocated on our behalf. This is a little tricky since that happens
inside parse_object(), and it doesn't tell us whether the object was
already parsed, or whether it allocated the buffer itself. But by
checking for an already-parsed tree beforehand, we can distinguish the
two cases.

That feels a little hacky, and does incur an extra lookup in the
object-hash table. But that cost is fairly minimal compared to actually
loading objects (and since we're iterating the whole pack here, we're
likely to be loading most objects, rather than reusing cached results).

It may also be a good direction for this function in general, as there
are other possible optimizations that rely on doing some analysis before
parsing:

  - we could detect blobs and avoid reading their contents; they can't
    link to other objects, but parse_object() doesn't know that we don't
    care about checking their hashes.

  - we could avoid allocating object structs entirely for most objects
    (since we really only need them in the oidset), which would save
    some memory.

  - promisor commits could use the commit-graph rather than loading the
    object from disk

This commit doesn't do any of those optimizations, but I think it argues
that this direction is reasonable, rather than relying on parse_object()
and trying to teach it to give us more information about whether it
parsed.

The included test fails reliably under SANITIZE=address just when
running "rev-list --missing=allow-promisor". Checking the output isn't
strictly necessary to detect the bug, but it seems like a reasonable
addition given the general lack of coverage for "allow-promisor" in the
test suite.

Reported-by: Andrew Olsen &lt;andrew.olsen@koordinates.com&gt;
Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>tree-walk: add a mechanism for getting non-canonicalized modes</title>
<updated>2022-08-10T21:26:25Z</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2022-08-10T21:01:17Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=ec18b10bf20574fc6d60c966412a11c81f9c17e0'/>
<id>urn:sha1:ec18b10bf20574fc6d60c966412a11c81f9c17e0</id>
<content type='text'>
When using init_tree_desc() and tree_entry() to iterate over a tree, we
always canonicalize the modes coming out of the tree. This is a good
thing to prevent bugs or oddities in normal code paths, but it's
counter-productive for tools like fsck that want to see the exact
contents.

We can address this by adding an option to avoid the extra
canonicalization. A few notes on the implementation:

  - I've attached the new option to the tree_desc struct itself. The
    actual code change is in decode_tree_entry(), which is in turn
    called by the public update_tree_entry(), tree_entry(), and
    init_tree_desc() functions, plus their "gently" counterparts.

    By letting it ride along in the struct, we can avoid changing the
    signature of those functions, which are called many times. Plus it's
    conceptually simpler: you really want a particular iteration of a
    tree to be "raw" or not, rather than individual calls.

  - We still have to set the new option somewhere. The struct is
    initialized by init_tree_desc(). I added the new flags field only to
    the "gently" version. That avoids disturbing the much more numerous
    non-gentle callers, and it makes sense that anybody being careful
    about looking at raw modes would also be careful about bogus trees
    (i.e., the caller will be something like fsck in the first place).

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'tb/cruft-packs'</title>
<updated>2022-06-03T21:30:37Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2022-06-03T21:30:37Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=a50036da1a39806a8ae1aba2e2f2fea6f7fb8e08'/>
<id>urn:sha1:a50036da1a39806a8ae1aba2e2f2fea6f7fb8e08</id>
<content type='text'>
A mechanism to pack unreachable objects into a "cruft pack",
instead of ejecting them into loose form to be reclaimed later, has
been introduced.

* tb/cruft-packs:
  sha1-file.c: don't freshen cruft packs
  builtin/gc.c: conditionally avoid pruning objects via loose
  builtin/repack.c: add cruft packs to MIDX during geometric repack
  builtin/repack.c: use named flags for existing_packs
  builtin/repack.c: allow configuring cruft pack generation
  builtin/repack.c: support generating a cruft pack
  builtin/pack-objects.c: --cruft with expiration
  reachable: report precise timestamps from objects in cruft packs
  reachable: add options to add_unseen_recent_objects_to_traversal
  builtin/pack-objects.c: --cruft without expiration
  builtin/pack-objects.c: return from create_object_entry()
  t/helper: add 'pack-mtimes' test-tool
  pack-mtimes: support writing pack .mtimes files
  chunk-format.h: extract oid_version()
  pack-write: pass 'struct packing_data' to 'stage_tmp_packfiles'
  pack-mtimes: support reading .mtimes files
  Documentation/technical: add cruft-packs.txt
</content>
</entry>
<entry>
<title>pack-mtimes: support reading .mtimes files</title>
<updated>2022-05-26T22:48:26Z</updated>
<author>
<name>Taylor Blau</name>
<email>me@ttaylorr.com</email>
</author>
<published>2022-05-20T23:17:35Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=94cd775a6c52a99caeb1278c3d8044ee109e2d3e'/>
<id>urn:sha1:94cd775a6c52a99caeb1278c3d8044ee109e2d3e</id>
<content type='text'>
To store the individual mtimes of objects in a cruft pack, introduce a
new `.mtimes` format that can optionally accompany a single pack in the
repository.

The format is defined in Documentation/technical/pack-format.txt, and
stores a 4-byte network order timestamp for each object in name (index)
order.

This patch prepares for cruft packs by defining the `.mtimes` format,
and introducing a basic API that callers can use to read out individual
mtimes.

Signed-off-by: Taylor Blau &lt;me@ttaylorr.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'ep/maint-equals-null-cocci' for maint-2.35</title>
<updated>2022-05-02T17:06:04Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2022-05-02T17:06:00Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=2b0a58d164b0642be3eeb476fecd28114445cdd5'/>
<id>urn:sha1:2b0a58d164b0642be3eeb476fecd28114445cdd5</id>
<content type='text'>
* ep/maint-equals-null-cocci:
  tree-wide: apply equals-null.cocci
  contrib/coccinnelle: add equals-null.cocci
</content>
</entry>
<entry>
<title>tree-wide: apply equals-null.cocci</title>
<updated>2022-05-02T16:50:37Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2022-05-02T16:50:37Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=afe8a9070bc62db9cfde1e30147178c40d391d93'/>
<id>urn:sha1:afe8a9070bc62db9cfde1e30147178c40d391d93</id>
<content type='text'>
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'jt/pack-header-lshift-overflow'</title>
<updated>2022-01-12T23:11:41Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2022-01-12T23:11:41Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=c9c082850d263f073483ebcaa118c3f8be2061c4'/>
<id>urn:sha1:c9c082850d263f073483ebcaa118c3f8be2061c4</id>
<content type='text'>
* jt/pack-header-lshift-overflow:
  packfile: fix off-by-one error in decoding logic
</content>
</entry>
<entry>
<title>packfile: fix off-by-one error in decoding logic</title>
<updated>2022-01-12T20:14:49Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2022-01-12T20:11:42Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=a5c97b016421a2869b460bbf6bdcd43dc186d433'/>
<id>urn:sha1:a5c97b016421a2869b460bbf6bdcd43dc186d433</id>
<content type='text'>
shift count being exactly at 7-bit smaller than the long is OK; on
32-bit architecture, shift count starts at 4 and goes through 11, 18
and 25, at which point the guard triggers one iteration too early.

Reported-by: Marc Strapetz &lt;marc.strapetz@syntevo.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'tb/pack-revindex-on-disk-cleanup'</title>
<updated>2021-12-15T17:39:50Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2021-12-15T17:39:50Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=79aee56c1ee342953a6d9f49f45b89d7f44a624f'/>
<id>urn:sha1:79aee56c1ee342953a6d9f49f45b89d7f44a624f</id>
<content type='text'>
Code clean-up.

* tb/pack-revindex-on-disk-cleanup:
  packfile: make `close_pack_revindex()` static
</content>
</entry>
</feed>
