All of lore.kernel.org
 help / color / mirror / Atom feed
From: "René Scharfe" <l.s.r@web.de>
To: Junio C Hamano <gitster@pobox.com>
Cc: Git List <git@vger.kernel.org>
Subject: Re: [PATCH] imap-send: handle NULL return of next_arg()
Date: Thu, 2 Nov 2017 18:27:05 +0100	[thread overview]
Message-ID: <e71377c8-ce87-c7f4-138a-41dc1cc6f3dc@web.de> (raw)
In-Reply-To: <xmqqefphs9rx.fsf@gitster.mtv.corp.google.com>

Am 02.11.2017 um 03:18 schrieb Junio C Hamano:
> René Scharfe <l.s.r@web.de> writes:
> 
>> @@ -807,6 +816,8 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd)
>>   			if (cmdp->cb.cont || cmdp->cb.data)
>>   				imap->literal_pending = 0;
>>   			arg = next_arg(&cmd);
>> +			if (!arg)
>> +				arg = "";
> 
> This is being cute and needs reading of the post-context a bit.
> 
>           arg = next_arg(&cmd);
> +        if (!arg)
> +                arg = "";
>           if (!strcmp("OK", arg))
>                   resp = DRV_OK;
>           else {
>                   if (!strcmp("NO", arg))
>                           resp = RESP_NO;
>                   else /*if (!strcmp("BAD", arg))*/
>                           resp = RESP_BAD;
>                   fprintf(stderr, "IMAP command '%s' returned response (%s) - %s\n",
>                           !starts_with(cmdp->cmd, "LOGIN") ?
>                                           cmdp->cmd : "LOGIN <user> <pass>",
>                                           arg, cmd ? cmd : "");
>           }
>           if ((resp2 = parse_response_code(ctx, &cmdp->cb, cmd)) > resp)
>                   resp = resp2;
> 
> 
> Because the existing code does not explicitly check for "BAD", we
> get RESP_BAD, which is what we want in the end, and the error
> message we give has "returned response (%s)" which is filled with
> this empty string.
> 
> I notice that when this change matters, i.e. we hit a premature end,
> next_arg() that yielded NULL would have cleared cmd.  That is OK for
> the fprintf() we see above, but wouldn't it hit parse_response_code()
> that is shared between good and bad cases?  The function starts like
> so:
> 
>      static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb,
>                                     char *s)
>      {
>              struct imap *imap = ctx->imap;
>              char *arg, *p;
> 
>              if (*s != '[')
>                      return RESP_OK;		/* no response code */
> 
> so we will get an immediate NULL dereference, it appears.

Good catch.

The NULL check in the fprintf() call (two lines above) makes it obvious
already that cmd can be NULL.  So parse_response_code() needs to learn
to handle NULL passed as its third parameter.  And since "no response
code" yields "RESP_OK" I guess that this should be an appropriate
reaction to s == NULL as well.

RFC 3501 seems to agree (response codes are optional):

   7.1.    Server Responses - Status Responses

   Status responses are OK, NO, BAD, PREAUTH and BYE.  OK, NO, and BAD
   can be tagged or untagged.  PREAUTH and BYE are always untagged.

   Status responses MAY include an OPTIONAL "response code".  A response
   code consists of data inside square brackets in the form of an atom,
   possibly followed by a space and arguments.  The response code
   contains additional information or status codes for client software
   beyond the OK/NO/BAD condition, and are defined when there is a
   specific action that a client can take based upon the additional
   information.

The follow-up patch below makes sense in this light, but I wonder why
it hasn't been necessary so far.  Do most IMAP servers actually send
response codes?  Or at least some other string after a status response?
Are no users of git imap-send left?  I have no way to test any of that.
:-(

René

-- >8 --
Subject: [PATCH 2/1] imap-send: handle missing response codes gracefully

Response codes are optional.  Exit parse_response_code() early if it's
passed a NULL string, indicating that we reached the end of the reply.
This avoids dereferencing said NULL pointer.

Noticed-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Rene Scharfe <l.s.r@web.de>
---
 imap-send.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/imap-send.c b/imap-send.c
index 0031566309..12cc4ea4c8 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -684,7 +684,7 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb,
 	struct imap *imap = ctx->imap;
 	char *arg, *p;
 
-	if (*s != '[')
+	if (!s || *s != '[')
 		return RESP_OK;		/* no response code */
 	s++;
 	if (!(p = strchr(s, ']'))) {
-- 
2.15.0

      reply	other threads:[~2017-11-02 17:27 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-01 17:03 [PATCH] imap-send: handle NULL return of next_arg() René Scharfe
2017-11-02  2:18 ` Junio C Hamano
2017-11-02 17:27   ` René Scharfe [this message]

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=e71377c8-ce87-c7f4-138a-41dc1cc6f3dc@web.de \
    --to=l.s.r@web.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.