{"thread":{"id":"47789","subject":"[PATCH 1/2] correct error messages for NULL packet_read_line()","startedAt":"2018-02-08T18:56:46Z","lastAt":"2018-02-08T18:58:49Z","messageCount":4,"participants":["Jon Simons","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"338748","messageId":"1518115670-2646-2-git-send-email-jon@jonsimons.org","threadId":"47789","inReplyTo":"1518115670-2646-1-git-send-email-jon@jonsimons.org","subject":"[PATCH 1/2] correct error messages for NULL packet_read_line()","fromName":"Jon Simons","fromEmail":"jon@jonsimons.org","sentAt":"2018-02-08T18:47:49Z","receivedAt":"2018-02-08T18:56:46Z","isPatch":true,"sender":{"key":"jon@jonsimons.org","avatar":"https://avatars.githubusercontent.com/u/118440?v=4"},"body":"From: Jeff King <peff@peff.net>\n\nThe packet_read_line() function dies if it gets an\nunexpected EOF. It only returns NULL if we get a flush\npacket (or technically, a zero-length \"0004\" packet, but\nnobody is supposed to send those, and they are\nindistinguishable from a flush in this interface).\n\nLet's correct error messages which claim an unexpected EOF;\nit's really an unexpected flush packet.\n\nWhile we're here, let's also check \"!line\" instead of\n\"!len\" in the second case. The two events should always\ncoincide, but checking \"!line\" makes it more obvious that we\nare not about to dereference NULL.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n builtin/archive.c | 2 +-\n fetch-pack.c      | 4 ++--\n 2 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/archive.c b/builtin/archive.c\nindex f863465..73971d0 100644\n--- a/builtin/archive.c\n+++ b/builtin/archive.c\n@@ -55,7 +55,7 @@ static int run_remote_archiver(int argc, const char **argv,\n \n \tbuf = packet_read_line(fd[0], NULL);\n \tif (!buf)\n-\t\tdie(_(\"git archive: expected ACK/NAK, got EOF\"));\n+\t\tdie(_(\"git archive: expected ACK/NAK, got a flush packet\"));\n \tif (strcmp(buf, \"ACK\")) {\n \t\tif (starts_with(buf, \"NACK \"))\n \t\t\tdie(_(\"git archive: NACK %s\"), buf + 5);\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex a376b4e..1b7cd6b 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -262,8 +262,8 @@ static enum ack_type get_ack(int fd, struct object_id *result_oid)\n \tchar *line = packet_read_line(fd, &len);\n \tconst char *arg;\n \n-\tif (!len)\n-\t\tdie(_(\"git fetch-pack: expected ACK/NAK, got EOF\"));\n+\tif (!line)\n+\t\tdie(_(\"git fetch-pack: expected ACK/NAK, got a flush packet\"));\n \tif (!strcmp(line, \"NAK\"))\n \t\treturn NAK;\n \tif (skip_prefix(line, \"ACK \", &arg)) {\n-- \n2.1.4\n\n"},{"id":"338749","messageId":"1518115670-2646-1-git-send-email-jon@jonsimons.org","threadId":"47789","inReplyTo":null,"subject":"[PATCH 0/2] Fix NULL checks for some packet_read_line call sites","fromName":"Jon Simons","fromEmail":"jon@jonsimons.org","sentAt":"2018-02-08T18:47:48Z","receivedAt":"2018-02-08T18:56:48Z","isPatch":true,"sender":{"key":"jon@jonsimons.org","avatar":"https://avatars.githubusercontent.com/u/118440?v=4"},"body":"Included here are a couple of fixes and cleanups for\nhandling NULL return values from 'packet_read_line'.\n\nJeff King (1):\n  correct error messages for NULL packet_read_line()\n\nJon Simons (1):\n  always check for NULL return from packet_read_line()\n\n builtin/archive.c | 2 +-\n fetch-pack.c      | 4 ++--\n remote-curl.c     | 2 ++\n send-pack.c       | 2 ++\n 4 files changed, 7 insertions(+), 3 deletions(-)\n\n-- \n2.1.4\n\n"},{"id":"338750","messageId":"1518115670-2646-3-git-send-email-jon@jonsimons.org","threadId":"47789","inReplyTo":"1518115670-2646-1-git-send-email-jon@jonsimons.org","subject":"[PATCH 2/2] always check for NULL return from packet_read_line()","fromName":"Jon Simons","fromEmail":"jon@jonsimons.org","sentAt":"2018-02-08T18:47:50Z","receivedAt":"2018-02-08T18:57:02Z","isPatch":true,"sender":{"key":"jon@jonsimons.org","avatar":"https://avatars.githubusercontent.com/u/118440?v=4"},"body":"The packet_read_line() function will die if it sees any\nprotocol or socket errors. But it will return NULL for a\nflush packet; some callers which are not expecting this may\ndereference NULL if they get an unexpected flush. This would\ninvolve the other side breaking protocol, but we should\nflag the error rather than segfault.\n\nSigned-off-by: Jon Simons <jon@jonsimons.org>\n---\n remote-curl.c | 2 ++\n send-pack.c   | 2 ++\n 2 files changed, 4 insertions(+)\n\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 0053b09..9903077 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -339,6 +339,8 @@ static struct discovery *discover_refs(const char *service, int for_push)\n \t\t * pkt-line matches our request.\n \t\t */\n \t\tline = packet_read_line_buf(&last->buf, &last->len, NULL);\n+\t\tif (!line)\n+\t\t\tdie(\"invalid server response; expected service, got flush packet\");\n \n \t\tstrbuf_reset(&exp);\n \t\tstrbuf_addf(&exp, \"# service=%s\", service);\ndiff --git a/send-pack.c b/send-pack.c\nindex 11d6f3d..d37b265 100644\n--- a/send-pack.c\n+++ b/send-pack.c\n@@ -147,6 +147,8 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struc\n static int receive_unpack_status(int in)\n {\n \tconst char *line = packet_read_line(in, NULL);\n+\tif (!line)\n+\t\treturn error(_(\"unexpected flush packet while reading remote unpack status\"));\n \tif (!skip_prefix(line, \"unpack \", &line))\n \t\treturn error(_(\"unable to parse remote unpack status: %s\"), line);\n \tif (strcmp(line, \"ok\"))\n-- \n2.1.4\n\n"},{"id":"338751","messageId":"20180208185842.GA1814@sigill.intra.peff.net","threadId":"47789","inReplyTo":"1518115670-2646-3-git-send-email-jon@jonsimons.org","subject":"Re: [PATCH 2/2] always check for NULL return from packet_read_line()","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-02-08T18:58:42Z","receivedAt":"2018-02-08T18:58:49Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Feb 08, 2018 at 01:47:50PM -0500, Jon Simons wrote:\n\n> The packet_read_line() function will die if it sees any\n> protocol or socket errors. But it will return NULL for a\n> flush packet; some callers which are not expecting this may\n> dereference NULL if they get an unexpected flush. This would\n> involve the other side breaking protocol, but we should\n> flag the error rather than segfault.\n\nAs one might guess from the dual authorship on this series, Jon and I\ndiscussed these off list. So this one is\n\n  Reviewed-by: Jeff King <peff@peff.net>\n\nAnd the other one, too, but I'm not sure that carries any weight. :)\n\n-Peff\n"}]}