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

Re: [PATCH] Always check the return value of `repo_read_object_file()`

From
Kyle Lippincott <spectral@google.com>
Date
Feb 6, 2024, 01:13 UTC
Message-ID
<CAO_smVhrMn=-uF1B6+RA8A+VLCEN=o57zbQPtr8hpxRKY=qJRQ@mail.gmail.com>
In-Reply-To
<pull.1650.git.1707143753726.gitgitgadget@gmail.com>

On Mon, Feb 5, 2024 at 6:36 AM Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> wrote:

Show 45 quoted lines
>
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> There are a couple of places in Git's source code where the return value
> is not checked. As a consequence, they are susceptible to segmentation
> faults.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>     Always check the return value of repo_read_object_file()
>
>     I ran into this today, when I had tried git am -3 to import changes from
>     a repository into a different repository that has the first repository's
>     code vendored in. To make this work, I set
>     GIT_ALTERNATE_OBJECT_DIRECTORIES accordingly for the git am -3 call, but
>     forgot to set it for a subsequent git diff call, which then segfaulted.
>
>     There are still a couple of places left where there are checks but they
>     look dubious to me, as they simply continue as if an empty blob had been
>     read, for example in builtin/tag.c. However, there are checks that avoid
>     segfaults, so I left them alone.
>
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1650%2Fdscho%2Fsafer-object-reads-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1650/dscho/safer-object-reads-v1
> Pull-Request: https://github.com/gitgitgadget/git/pull/1650
>
>  bisect.c           |  3 +++
>  builtin/cat-file.c | 10 ++++++++--
>  builtin/grep.c     |  2 ++
>  builtin/notes.c    |  6 ++++--
>  combine-diff.c     |  2 ++
>  rerere.c           |  3 +++
>  6 files changed, 22 insertions(+), 4 deletions(-)
>
> diff --git a/builtin/notes.c b/builtin/notes.c
> index e65cae0bcf7..caf20fd5bdd 100644
> --- a/builtin/notes.c
> +++ b/builtin/notes.c
> @@ -716,9 +716,11 @@ static int append_edit(int argc, const char **argv, const char *prefix)
>                 struct strbuf buf = STRBUF_INIT;
>                 char *prev_buf = repo_read_object_file(the_repository, note, &type, &size);
>
> -               if (prev_buf && size)
> +               if (!prev_buf)
> +                       die(_("unable to read %s"), oid_to_hex(note));

This changes the behavior of this function. Previously, it would not add prev_buf output, but still succeed. This now dies.

Show 17 quoted lines
> +               if (size)
>                         strbuf_add(&buf, prev_buf, size);
> -               if (d.buf.len && prev_buf && size)
> +               if (d.buf.len && size)
>                         append_separator(&buf);
>                 strbuf_insert(&d.buf, 0, buf.buf, buf.len);
>
> diff --git a/combine-diff.c b/combine-diff.c
> index db94581f724..d6d6fa16894 100644
> --- a/combine-diff.c
> +++ b/combine-diff.c
> @@ -337,6 +337,8 @@ static char *grab_blob(struct repository *r,
>                 free_filespec(df);
>         } else {
>                 blob = repo_read_object_file(r, oid, &type, size);
> +               if (!blob)
> +                       die(_("unable to read %s"), oid_to_hex(oid));

Technically this is changing the output, but I think that's good - I believe that previously the behavior was undefined, because `type` wouldn't be modified if the blob didn't exist, and `type` wasn't assigned a value earlier in the function.

Show 8 quoted lines
>                 if (type != OBJ_BLOB)
>                         die("object '%s' is not a blob!", oid_to_hex(oid));
>         }
>
> base-commit: 2a540e432fe5dff3cfa9d3bf7ca56db2ad12ebb9
> --
> gitgitgadget
>
Previous: Johannes SchindelinNext: Johannes Schindelin
Message 5 of 16 in “Always check the return value of `repo_read_object_file()`”
  1. Always check the return value of `repo_read_object_file()`Johannes Schindelin via GitGitGadget, Feb 5, 2024
  2. Karthik NayakFeb 5, 2024
  3. Junio C HamanoFeb 6, 2024
  4. Johannes SchindelinFeb 12, 2024
  5. Kyle LippincottFeb 6, 2024
  6. Johannes SchindelinFeb 9, 2024
  7. Junio C HamanoFeb 9, 2024
  8. Kyle LippincottFeb 9, 2024
  9. Patrick SteinhardtFeb 6, 2024
  10. Junio C HamanoFeb 6, 2024
  11. Johannes SchindelinFeb 9, 2024
  12. Patrick SteinhardtFeb 9, 2024
  13. Junio C HamanoFeb 6, 2024
  14. Johannes SchindelinFeb 12, 2024
  15. Always check the return value of `repo_read_object_file()`Teng Long, Feb 16, 2024
  16. Johannes SchindelinFeb 18, 2024

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.