git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 0/3] Fix uninitialised reads found with MSAN

From
Andrzej Hunt via GitGitGadget <gitgitgadget@gmail.com>
Date
Jun 14, 2021, 15:51 UTC
Message-ID
<pull.1033.v2.git.git.1623685877.gitgitgadget@gmail.com>
In-Reply-To
<pull.1033.git.git.1623343712.gitgitgadget@gmail.com>

V2 replaces an #if'd memset with some brace initialisation (patch 3/3) as per review comments.

I've also removed an irrelevant "technically" from commit message 2/3, and fixed a typo in commit message 3/3.

Andrzej Hunt (3):
  bulk-checkin: make buffer reuse more obvious and safer
  split-index: use oideq instead of memcmp to compare object_id's
  builtin/checkout--worker: zero-initialise struct to avoid MSAN
    complaints
 builtin/checkout--worker.c | 2 +-
 bulk-checkin.c             | 3 +--
 split-index.c              | 3 ++-
 3 files changed, 4 insertions(+), 4 deletions(-)
base-commit: 62a8d224e6203d9d3d2d1d63a01cf5647ec312c9
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1033%2Fahunt%2Fmsan-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1033/ahunt/msan-v2
Pull-Request: https://github.com/git/git/pull/1033
Range-diff vs v1:
 1:  7659d4bf13c2 = 1:  7659d4bf13c2 bulk-checkin: make buffer reuse more obvious and safer
 2:  14b0d5dd7fce ! 2:  6943eb511bee split-index: use oideq instead of memcmp to compare object_id's
     @@ Commit message
          include that field when calling memcmp on a subset of the cache_entry.
          Depending on which hashing algorithm is being used, only part of
          object_id.hash is actually being used, therefore including it in a
     -    memcmp() is technically incorrect. Instead we choose to exclude the
     -    object_id when calling memcmp(), and call oideq() separately.
     +    memcmp() is incorrect. Instead we choose to exclude the object_id when
     +    calling memcmp(), and call oideq() separately.
      
          This issue was found when running t1700-split-index with MSAN, see MSAN
          output below (on my machine, offset 76 corresponds to 4 bytes after the
 3:  cd1e1f6985c7 ! 3:  4bdc0b77f6f2 builtin/checkout--worker: memset struct to avoid MSAN complaints
     @@ Metadata
      Author: Andrzej Hunt <ajrhunt@google.com>
      
       ## Commit message ##
     -    builtin/checkout--worker: memset struct to avoid MSAN complaints
     +    builtin/checkout--worker: zero-initialise struct to avoid MSAN complaints
      
          report_result() sends a struct to the parent process, but that struct
     -    contains unintialised padding bytes. Running this code under MSAN
     -    rightly triggers a warning - but we also don't care about this warning
     -    because we control the receiving code, and we therefore know that those
     -    padding bytes won't be read on the receiving end. Therefore we add a
     -    memset to convince MSAN that this memory is safe to read - but only
     -    when building with MSAN to avoid this cost in normal usage.
     +    would contain uninitialised padding bytes. Running this code under MSAN
     +    rightly triggers a warning - but we don't particularly care about this
     +    warning because we control the receiving code, and we therefore know
     +    that those padding bytes won't be read on the receiving end.
     +
     +    We could simply suppress this warning under MSAN with the approporiate
     +    ifdef'd attributes, but a less intrusive solution is to 0-initialise the
     +    struct, which guarantees that the padding will also be initialised.
      
          Interestingly, in the error-case branch, we only try to copy the first
          two members of pc_item_result, by copying only PC_ITEM_RESULT_BASE_SIZE
     @@ Commit message
          after the end of the second last member. We could avoid doing this by
          redefining PC_ITEM_RESULT_BASE_SIZE as
          'offsetof(second_last_member) + sizeof(second_last_member)', but there's
     -    no huge benefit to doing so (and our memset hack silences the MSAN
     -    warning in this scenario either way).
     +    no huge benefit to doing so (and this patch silences the MSAN warning in
     +    this scenario either way).
      
          MSAN output from t2080 (partially interleaved due to the
          parallel work :) ):
     @@ Commit message
          Signed-off-by: Andrzej Hunt <andrzej@ahunt.org>
      
       ## builtin/checkout--worker.c ##
     -@@ builtin/checkout--worker.c: static void report_result(struct parallel_checkout_item *pc_item)
     - 	struct pc_item_result res;
     +@@ builtin/checkout--worker.c: static void packet_to_pc_item(const char *buffer, int len,
     + 
     + static void report_result(struct parallel_checkout_item *pc_item)
     + {
     +-	struct pc_item_result res;
     ++	struct pc_item_result res = { 0 };
       	size_t size;
       
     -+#if defined(__has_feature)
     -+#  if __has_feature(memory_sanitizer)
     -+	// MSAN workaround: res contains padding bytes, which will remain
     -+	// permanently unintialised. Later, we read all of res in order to send
     -+	// it to the parent process - and MSAN (rightly) complains that we're
     -+	// reading those unintialised padding bytes. By memset'ing res we
     -+	// guarantee that there are no uninitialised bytes.
     -+	memset(&res, 0, sizeof(res));
     -+#endif
     -+#endif
     -+
       	res.id = pc_item->id;
     - 	res.status = pc_item->status;
     - 
-- 
gitgitgadget
Previous: Jeff KingNext: Andrzej Hunt via GitGitGadget
Message 10 of 15 in “Fix uninitialised reads found with MSAN”
  1. 0/3 Fix uninitialised reads found with MSANAndrzej Hunt via GitGitGadget, Jun 10, 2021
  2. 2/3 split-index: use oideq instead of memcmp to compare object_id'sAndrzej Hunt via GitGitGadget, Jun 10, 2021
  3. 3/3 builtin/checkout--worker: memset struct to avoid MSAN complaintsAndrzej Hunt via GitGitGadget, Jun 10, 2021
  4. Chris TorekJun 11, 2021
  5. Junio C HamanoJun 11, 2021
  6. Andrzej HuntJun 11, 2021
  7. Junio C HamanoJun 14, 2021
  8. 1/3 bulk-checkin: make buffer reuse more obvious and saferAndrzej Hunt via GitGitGadget, Jun 10, 2021
  9. Jeff KingJun 11, 2021
  10. 0/3 Fix uninitialised reads found with MSANAndrzej Hunt via GitGitGadget, Jun 14, 2021
  11. 1/3 bulk-checkin: make buffer reuse more obvious and saferAndrzej Hunt via GitGitGadget, Jun 14, 2021
  12. 2/3 split-index: use oideq instead of memcmp to compare object_id'sAndrzej Hunt via GitGitGadget, Jun 14, 2021
  13. 3/3 builtin/checkout--worker: zero-initialise struct to avoid MSAN complaintsAndrzej Hunt via GitGitGadget, Jun 14, 2021
  14. Philip OakleyJun 17, 2021
  15. Andrzej HuntJun 20, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.