git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: Lidong Yan via GitGitGadget <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org, Lidong Yan <502024330056@smail.nju.edu.cn>
Subject: Re: [PATCH v2] parse-options: fix xstrdup leak in parse_options_step parse-options:984
Date: Fri, 9 May 2025 08:19:56 +0200	[thread overview]
Message-ID: <aB2ejA1tCK9DR1Nq@pks.im> (raw)
In-Reply-To: <pull.1954.v2.git.git.1746624294017.gitgitgadget@gmail.com>

On Wed, May 07, 2025 at 01:24:53PM +0000, Lidong Yan via GitGitGadget wrote:
> From: Lidong Yan <502024330056@smail.nju.edu.cn>
> 
> Most Git commands use parse_options to parse options, but parse_options
> causes a memory leak when it encounters unknown short options. The leak
> occurs at line 984 in parse-options.c, where git allocates some spaces

Again, no need to quote the exact line number.

> to store the unknown short options and will never release those spaces.
> 
> To address this issue, users can be allowed to provide a custom function
> to allocate memory for unknown options. For example, users can use
> strvec_push to allocate memory for unknown options and later call
> strvec_clear at the end of the Git command to release the memory, thereby
> avoiding the memory leak.

So does that mean that _every_ user of the "parse-options" interfaces
now has to explicitly plug this memory leak when facing unknown options?
That sounds rather undesirable, as there are so many users out there.

> This commit allows users to provide a custom allocation function for
> unknown options via the strdup_fn field in the last struct option. For
> convenience, this commit also introduces a new macro, OPT_UNKNOWN, which
> behaves like OPT_END but takes an additional argument for the allocation
> function. parse_options could get the custom allocation function in struct
> parse_opt_ctx_t by using set_strdup_fn. A simple example to use
> OPT_UNKNOWN is put into t/helper/test-free-unknown-options.c

Hm. Is there any other usecase for the `strdup_fn` field that you can
think about in the future? Otherwise it feels a bit overengineered from
my perspective.

I unfortuntaely don't think the proposed solution works well. To really
plug the memory leak everywhere, we would have to convert every single
user of `parse_options()` to pass `OPTION_UNKNOWN()` instead of
`OPTION_END()`, pass a strvec and clear that strvec at the end. It just
doesn't quite feel like it's worth it to plug a single, bounded memory
leak.

The most important problem that we're facing is that the allocated
string has a lifetime longer than `parse_options()`, because it really
only becomes relevant in the case where `PARSE_OPT_KEEP_UNKNOWN_OPT` is
enabled. If so, the _caller_ of `parse_options()` will want to process
the modified `argv`, and thus they have to be the ones responsible for
freeing potentially-allocated memory once it's unused.

But that'd require us to keep some state. You solve this via the extra
strvec, but that doesn't really look like a great solution to me. An
alternative would be to expose the `parse_options_ctx` and let the
caller eventually call `parse_options_clear()` or something like that.
This would also require us to modify every caller, but the benefit would
be that we now have a single place where we can always allocate memory
in without having to worry about its lifetime.

All of that starts to become kind of involved though. So unless others
disagree with my analysis I just don't think this edge case really is
worth the complexity.

Thanks!

Patrick

  reply	other threads:[~2025-05-09  6:20 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-07  2:33 [PATCH 0/3] fix xstrdup leak in parse_short_opt Lidong Yan via GitGitGadget
2025-05-07  2:33 ` [PATCH 1/3] " Lidong Yan via GitGitGadget
2025-05-07  7:54   ` Patrick Steinhardt
2025-05-07  2:33 ` [PATCH 2/3] fix: replace bug where int was incorrectly used as bool Lidong Yan via GitGitGadget
2025-05-07  7:54   ` Patrick Steinhardt
2025-05-07  2:33 ` [PATCH 3/3] fix: use strvec_push_wrapper to prevent ubsan failure Lidong Yan via GitGitGadget
2025-05-07  7:54   ` Patrick Steinhardt
2025-05-07 12:19     ` lidongyan
2025-05-07 13:24 ` [PATCH v2] parse-options: fix xstrdup leak in parse_options_step parse-options:984 Lidong Yan via GitGitGadget
2025-05-09  6:19   ` Patrick Steinhardt [this message]
2025-05-09  7:35     ` lidongyan
2025-05-09 13:08     ` Phillip Wood
2025-05-09 13:43       ` lidongyan
2025-05-09 14:28   ` [PATCH v3] parse-options: fix memory leak when calling `parse_options` Lidong Yan via GitGitGadget

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=aB2ejA1tCK9DR1Nq@pks.im \
    --to=ps@pks.im \
    --cc=502024330056@smail.nju.edu.cn \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@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 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 NNTP newsgroup(s).