git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 1/2] gpg-interface: handle missing " with " gracefully in parse_ssh_output()
@ 2021-10-30 17:04 René Scharfe
  2021-10-30 17:07 ` [PATCH 2/2] gpg-interface: avoid buffer overrun " René Scharfe
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: René Scharfe @ 2021-10-30 17:04 UTC (permalink / raw)
  To: Git List; +Cc: Fabian Stelzer, Junio C Hamano

If the output of ssh-keygen starts with "Good \"git\" signature for ",
but is not followed by " with " for some reason, then parse_ssh_output()
uses -1 as the len parameter of xmemdupz(), which in turn will end the
program.  Reject the signature and carry on instead in that case.

Signed-off-by: René Scharfe <l.s.r@web.de>
---
This code was added after v2.33.0.
Patch formatted with --inter-hunk-context=2 for easier review.

Silly bonus question: What's the purpose of the "+ 1" and "- 1", which
seem to cancel each other out?

 gpg-interface.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/gpg-interface.c b/gpg-interface.c
index 800d8caa67..62d340e78a 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c
@@ -387,17 +387,19 @@ static void parse_ssh_output(struct signature_check *sigc)
 	line = to_free = xmemdupz(sigc->output, strcspn(sigc->output, "\n"));

 	if (skip_prefix(line, "Good \"git\" signature for ", &line)) {
-		/* Valid signature and known principal */
-		sigc->result = 'G';
-		sigc->trust_level = TRUST_FULLY;
-
 		/* Search for the last "with" to get the full principal */
 		principal = line;
 		do {
 			search = strstr(line, " with ");
 			if (search)
 				line = search + 1;
 		} while (search != NULL);
+		if (line == principal)
+			goto cleanup;
+
+		/* Valid signature and known principal */
+		sigc->result = 'G';
+		sigc->trust_level = TRUST_FULLY;
 		sigc->signer = xmemdupz(principal, line - principal - 1);
 	} else if (skip_prefix(line, "Good \"git\" signature with ", &line)) {
 		/* Valid signature, but key unknown */
--
2.33.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] gpg-interface: avoid buffer overrun in parse_ssh_output()
  2021-10-30 17:04 [PATCH 1/2] gpg-interface: handle missing " with " gracefully in parse_ssh_output() René Scharfe
@ 2021-10-30 17:07 ` René Scharfe
  2021-11-01  6:07   ` Junio C Hamano
  2021-11-01  8:33   ` Fabian Stelzer
  2021-11-01  6:08 ` [PATCH 1/2] gpg-interface: handle missing " with " gracefully " Junio C Hamano
  2021-11-01  8:40 ` Fabian Stelzer
  2 siblings, 2 replies; 8+ messages in thread
From: René Scharfe @ 2021-10-30 17:07 UTC (permalink / raw)
  To: Git List; +Cc: Fabian Stelzer, Junio C Hamano

If the string "key" we found in the output of ssh-keygen happens to be
located at the very end of the line, then going four characters further
leaves us beyond the end of the string.  Explicitly search for the
space after "key" to handle a missing one gracefully.

Signed-off-by: René Scharfe <l.s.r@web.de>
---
This code was added after v2.33.0.

 gpg-interface.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gpg-interface.c b/gpg-interface.c
index 62d340e78a..3838536f0a 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c
@@ -409,9 +409,9 @@ static void parse_ssh_output(struct signature_check *sigc)
 		goto cleanup;
 	}

-	key = strstr(line, "key");
+	key = strstr(line, "key ");
 	if (key) {
-		sigc->fingerprint = xstrdup(strstr(line, "key") + 4);
+		sigc->fingerprint = xstrdup(strstr(line, "key ") + 4);
 		sigc->key = xstrdup(sigc->fingerprint);
 	} else {
 		/*
--
2.33.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] gpg-interface: avoid buffer overrun in parse_ssh_output()
  2021-10-30 17:07 ` [PATCH 2/2] gpg-interface: avoid buffer overrun " René Scharfe
@ 2021-11-01  6:07   ` Junio C Hamano
  2021-11-01  8:33   ` Fabian Stelzer
  1 sibling, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2021-11-01  6:07 UTC (permalink / raw)
  To: René Scharfe; +Cc: Git List, Fabian Stelzer

René Scharfe <l.s.r@web.de> writes:

> If the string "key" we found in the output of ssh-keygen happens to be
> located at the very end of the line, then going four characters further
> leaves us beyond the end of the string.  Explicitly search for the
> space after "key" to handle a missing one gracefully.
>
> Signed-off-by: René Scharfe <l.s.r@web.de>
> ---
> This code was added after v2.33.0.

Thanks.

Fabian, we are in -rc phase where we concentrate on fixing bugs in
the new code in 'master'.  A quick ack, "here is a better way to fix
it", or "no, that won't be needed because..." is very much
appreciated.


>  gpg-interface.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/gpg-interface.c b/gpg-interface.c
> index 62d340e78a..3838536f0a 100644
> --- a/gpg-interface.c
> +++ b/gpg-interface.c
> @@ -409,9 +409,9 @@ static void parse_ssh_output(struct signature_check *sigc)
>  		goto cleanup;
>  	}
>
> -	key = strstr(line, "key");
> +	key = strstr(line, "key ");
>  	if (key) {
> -		sigc->fingerprint = xstrdup(strstr(line, "key") + 4);
> +		sigc->fingerprint = xstrdup(strstr(line, "key ") + 4);
>  		sigc->key = xstrdup(sigc->fingerprint);
>  	} else {
>  		/*
> --
> 2.33.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] gpg-interface: handle missing " with " gracefully in parse_ssh_output()
  2021-10-30 17:04 [PATCH 1/2] gpg-interface: handle missing " with " gracefully in parse_ssh_output() René Scharfe
  2021-10-30 17:07 ` [PATCH 2/2] gpg-interface: avoid buffer overrun " René Scharfe
@ 2021-11-01  6:08 ` Junio C Hamano
  2021-11-01  8:40 ` Fabian Stelzer
  2 siblings, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2021-11-01  6:08 UTC (permalink / raw)
  To: René Scharfe; +Cc: Git List, Fabian Stelzer

René Scharfe <l.s.r@web.de> writes:

> If the output of ssh-keygen starts with "Good \"git\" signature for ",
> but is not followed by " with " for some reason, then parse_ssh_output()
> uses -1 as the len parameter of xmemdupz(), which in turn will end the
> program.  Reject the signature and carry on instead in that case.
>
> Signed-off-by: René Scharfe <l.s.r@web.de>
> ---
> This code was added after v2.33.0.
> Patch formatted with --inter-hunk-context=2 for easier review.

Nice spotting.

> Silly bonus question: What's the purpose of the "+ 1" and "- 1", which
> seem to cancel each other out?

Fabian, we are in -rc phase where we concentrate on fixing bugs in
the new code in 'master'.  A quick ack, "here is a better way to fix
it", or "no, that won't be needed because..." is very much
appreciated.

Thanks.

>
>  gpg-interface.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/gpg-interface.c b/gpg-interface.c
> index 800d8caa67..62d340e78a 100644
> --- a/gpg-interface.c
> +++ b/gpg-interface.c
> @@ -387,17 +387,19 @@ static void parse_ssh_output(struct signature_check *sigc)
>  	line = to_free = xmemdupz(sigc->output, strcspn(sigc->output, "\n"));
>
>  	if (skip_prefix(line, "Good \"git\" signature for ", &line)) {
> -		/* Valid signature and known principal */
> -		sigc->result = 'G';
> -		sigc->trust_level = TRUST_FULLY;
> -
>  		/* Search for the last "with" to get the full principal */
>  		principal = line;
>  		do {
>  			search = strstr(line, " with ");
>  			if (search)
>  				line = search + 1;
>  		} while (search != NULL);
> +		if (line == principal)
> +			goto cleanup;
> +
> +		/* Valid signature and known principal */
> +		sigc->result = 'G';
> +		sigc->trust_level = TRUST_FULLY;
>  		sigc->signer = xmemdupz(principal, line - principal - 1);
>  	} else if (skip_prefix(line, "Good \"git\" signature with ", &line)) {
>  		/* Valid signature, but key unknown */
> --
> 2.33.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] gpg-interface: avoid buffer overrun in parse_ssh_output()
  2021-10-30 17:07 ` [PATCH 2/2] gpg-interface: avoid buffer overrun " René Scharfe
  2021-11-01  6:07   ` Junio C Hamano
@ 2021-11-01  8:33   ` Fabian Stelzer
  2021-11-01 17:44     ` Junio C Hamano
  1 sibling, 1 reply; 8+ messages in thread
From: Fabian Stelzer @ 2021-11-01  8:33 UTC (permalink / raw)
  To: René Scharfe, Git List; +Cc: Junio C Hamano

On 30.10.21 19:07, René Scharfe wrote:
> If the string "key" we found in the output of ssh-keygen happens to be
> located at the very end of the line, then going four characters further
> leaves us beyond the end of the string.  Explicitly search for the
> space after "key" to handle a missing one gracefully.
> 
> Signed-off-by: René Scharfe <l.s.r@web.de>
> ---
> This code was added after v2.33.0.
> 
>  gpg-interface.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/gpg-interface.c b/gpg-interface.c
> index 62d340e78a..3838536f0a 100644
> --- a/gpg-interface.c
> +++ b/gpg-interface.c
> @@ -409,9 +409,9 @@ static void parse_ssh_output(struct signature_check *sigc)
>  		goto cleanup;
>  	}
> 
> -	key = strstr(line, "key");
> +	key = strstr(line, "key ");
>  	if (key) {
> -		sigc->fingerprint = xstrdup(strstr(line, "key") + 4);
> +		sigc->fingerprint = xstrdup(strstr(line, "key ") + 4);
>  		sigc->key = xstrdup(sigc->fingerprint);
>  	} else {
>  		/*
> --
> 2.33.1
> 

Thanks. This is obviously correct.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] gpg-interface: handle missing " with " gracefully in parse_ssh_output()
  2021-10-30 17:04 [PATCH 1/2] gpg-interface: handle missing " with " gracefully in parse_ssh_output() René Scharfe
  2021-10-30 17:07 ` [PATCH 2/2] gpg-interface: avoid buffer overrun " René Scharfe
  2021-11-01  6:08 ` [PATCH 1/2] gpg-interface: handle missing " with " gracefully " Junio C Hamano
@ 2021-11-01  8:40 ` Fabian Stelzer
  2021-11-01 18:36   ` René Scharfe
  2 siblings, 1 reply; 8+ messages in thread
From: Fabian Stelzer @ 2021-11-01  8:40 UTC (permalink / raw)
  To: René Scharfe, Git List; +Cc: Junio C Hamano

On 30.10.21 19:04, René Scharfe wrote:
> If the output of ssh-keygen starts with "Good \"git\" signature for ",
> but is not followed by " with " for some reason, then parse_ssh_output()
> uses -1 as the len parameter of xmemdupz(), which in turn will end the
> program.  Reject the signature and carry on instead in that case.
> 
> Signed-off-by: René Scharfe <l.s.r@web.de>
> ---
> This code was added after v2.33.0.
> Patch formatted with --inter-hunk-context=2 for easier review.
> 
> Silly bonus question: What's the purpose of the "+ 1" and "- 1", which
> seem to cancel each other out?

They do. But only for the xmemdupz. It is important for the strstr() to
skip over already found strings (" with " could be in the principal name
as well - multiple times even). And doing strstr(line +1, ...) can be
problematic for the first iteration.

> 
>  gpg-interface.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/gpg-interface.c b/gpg-interface.c
> index 800d8caa67..62d340e78a 100644
> --- a/gpg-interface.c
> +++ b/gpg-interface.c
> @@ -387,17 +387,19 @@ static void parse_ssh_output(struct signature_check *sigc)
>  	line = to_free = xmemdupz(sigc->output, strcspn(sigc->output, "\n"));
> 
>  	if (skip_prefix(line, "Good \"git\" signature for ", &line)) {
> -		/* Valid signature and known principal */
> -		sigc->result = 'G';
> -		sigc->trust_level = TRUST_FULLY;
> -
>  		/* Search for the last "with" to get the full principal */
>  		principal = line;
>  		do {
>  			search = strstr(line, " with ");
>  			if (search)
>  				line = search + 1;
>  		} while (search != NULL);
> +		if (line == principal)
> +			goto cleanup;
> +
> +		/* Valid signature and known principal */
> +		sigc->result = 'G';
> +		sigc->trust_level = TRUST_FULLY;
>  		sigc->signer = xmemdupz(principal, line - principal - 1);
>  	} else if (skip_prefix(line, "Good \"git\" signature with ", &line)) {
>  		/* Valid signature, but key unknown */
> --
> 2.33.1
> 

The fix looks good otherwise.
Thanks!

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] gpg-interface: avoid buffer overrun in parse_ssh_output()
  2021-11-01  8:33   ` Fabian Stelzer
@ 2021-11-01 17:44     ` Junio C Hamano
  0 siblings, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2021-11-01 17:44 UTC (permalink / raw)
  To: Fabian Stelzer; +Cc: René Scharfe, Git List

Fabian Stelzer <fs@gigacodes.de> writes:

> On 30.10.21 19:07, René Scharfe wrote:
>> If the string "key" we found in the output of ssh-keygen happens to be
>> located at the very end of the line, then going four characters further
>> leaves us beyond the end of the string.  Explicitly search for the
>> space after "key" to handle a missing one gracefully.
>> 
>> Signed-off-by: René Scharfe <l.s.r@web.de>
>> ---
>> This code was added after v2.33.0.
>> 
>> 
>
> Thanks. This is obviously correct.

Thanks, both.  Will apply.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] gpg-interface: handle missing " with " gracefully in parse_ssh_output()
  2021-11-01  8:40 ` Fabian Stelzer
@ 2021-11-01 18:36   ` René Scharfe
  0 siblings, 0 replies; 8+ messages in thread
From: René Scharfe @ 2021-11-01 18:36 UTC (permalink / raw)
  To: Fabian Stelzer, Git List; +Cc: Junio C Hamano

Am 01.11.21 um 09:40 schrieb Fabian Stelzer:
> On 30.10.21 19:04, René Scharfe wrote:
>> Silly bonus question: What's the purpose of the "+ 1" and "- 1", which
>> seem to cancel each other out?
>
> They do. But only for the xmemdupz. It is important for the strstr() to
> skip over already found strings (" with " could be in the principal name
> as well - multiple times even). And doing strstr(line +1, ...) can be
> problematic for the first iteration.

Ah, right.

>>  		do {
>>  			search = strstr(line, " with ");
>>  			if (search)
>>  				line = search + 1;
>>  		} while (search != NULL);

This can be shortened to:

		while ((search = strstr(line, " with ")))
			line = search + 1;

I still would have tripped over the +1 / -1, though.  Calling an rfind()
or strrstr() or find_last() function that deals with it internally
would have helped me avoid that, I think, but we don't have use for such
a thing anywhere else.

René

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-11-01 18:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-30 17:04 [PATCH 1/2] gpg-interface: handle missing " with " gracefully in parse_ssh_output() René Scharfe
2021-10-30 17:07 ` [PATCH 2/2] gpg-interface: avoid buffer overrun " René Scharfe
2021-11-01  6:07   ` Junio C Hamano
2021-11-01  8:33   ` Fabian Stelzer
2021-11-01 17:44     ` Junio C Hamano
2021-11-01  6:08 ` [PATCH 1/2] gpg-interface: handle missing " with " gracefully " Junio C Hamano
2021-11-01  8:40 ` Fabian Stelzer
2021-11-01 18:36   ` René Scharfe

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).