Git development
 help / color / mirror / Atom feed
From: "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Johannes Schindelin <johannes.schindelin@gmx.de>,
	Johannes Schindelin <johannes.schindelin@gmx.de>
Subject: [PATCH 1/2] wincred: avoid memory corruption when erasing a credential
Date: Thu, 16 Jul 2026 14:27:50 +0000	[thread overview]
Message-ID: <3ceda5ed3d8f56fc84b3794b9bce918271e22a32.1784212072.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2182.git.1784212072.gitgitgadget@gmail.com>

From: Johannes Schindelin <johannes.schindelin@gmx.de>

The earlier d22a488482 (wincred: avoid memory corruption, 2025-11-17)
repaired only get_credential(); match_cred_password() has the same
defect and is reached on `git credential reject`. When Git asks the
helper to erase a stored credential whose password was supplied by
the caller, the helper copies the candidate's password into a freshly
allocated buffer for comparison. That copy overruns the allocation
by one WCHAR of NUL, which on uninstrumented Windows manifests as
process termination with status 0xC0000374. Because the helper can
die before reaching CredDeleteW(), `git credential reject` masks the
failure and the rejected credential remains stored.

CredentialBlobSize is documented as a byte count, so for an N-WCHAR
blob it equals N * sizeof(WCHAR). The pre-fix code allocated that
many bytes and asked wcsncpy_s to copy N wide characters, but
wcsncpy_s always appends a terminating NUL WCHAR, writing one WCHAR
past the allocation. The destination-capacity argument was also
passed in bytes rather than in WCHAR elements as the API requires,
so the safe-CRT runtime never rejected the copy.

See GHSA-rxqw-wxqg-g7hw.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 contrib/credential/wincred/git-credential-wincred.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c
index 73c2b9b72a..190bbccdf9 100644
--- a/contrib/credential/wincred/git-credential-wincred.c
+++ b/contrib/credential/wincred/git-credential-wincred.c
@@ -121,10 +121,10 @@ static int match_part_last(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim)
 
 static int match_cred_password(const CREDENTIALW *cred) {
 	int ret;
-	WCHAR *cred_password = xmalloc(cred->CredentialBlobSize);
-	wcsncpy_s(cred_password, cred->CredentialBlobSize,
-		(LPCWSTR)cred->CredentialBlob,
-		cred->CredentialBlobSize / sizeof(WCHAR));
+	size_t wlen = cred->CredentialBlobSize / sizeof(WCHAR);
+	WCHAR *cred_password = xmalloc((wlen + 1) * sizeof(WCHAR));
+	wcsncpy_s(cred_password, wlen + 1,
+		(LPCWSTR)cred->CredentialBlob, wlen);
 	ret = !wcscmp(cred_password, password);
 	free(cred_password);
 	return ret;
-- 
gitgitgadget


  reply	other threads:[~2026-07-16 14:27 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-16 14:27 [PATCH 0/2] Some wincred fixes Johannes Schindelin via GitGitGadget
2026-07-16 14:27 ` Johannes Schindelin via GitGitGadget [this message]
2026-07-16 14:27 ` [PATCH 2/2] wincred: prevent silent credential loss when storing OAuth tokens Johannes Schindelin 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=3ceda5ed3d8f56fc84b3794b9bce918271e22a32.1784212072.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=johannes.schindelin@gmx.de \
    /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