git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/1] protocol: limit max protocol version per service

From
Josh Steadmon <steadmon@google.com>
Date
Oct 2, 2018, 21:59 UTC
Message-ID
<59357266bd86e8e0ace9217a97717129a6f76188.1538516853.git.steadmon@google.com>
In-Reply-To
<cover.1538516853.git.steadmon@google.com>

For services other than git-receive-pack, clients currently advertise that they support the version set in the protocol.version config, regardless of whether or not there is actually an implementation of that service for the given protocol version. This causes backwards- compatibility problems when a new implementation for the given protocol version is added.

This patch sets maximum allowed protocol versions for git-receive-pack, git-upload-archive, and git-upload-pack.

Previously, git-receive-pack would downgrade from v2 to v0, but would allow v1 if set in protocol.version. Now, it will downgrade from v2 to v1.

Signed-off-by: Josh Steadmon <steadmon@google.com>
---
 connect.c     | 11 ++++-------
 protocol.c    | 13 +++++++++++++
 protocol.h    |  7 +++++++
 remote-curl.c | 11 ++++-------
 4 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/connect.c b/connect.c
index 94547e5056..4a8cd78239 100644
--- a/connect.c
+++ b/connect.c
@@ -1228,14 +1228,11 @@ struct child_process *git_connect(int fd[2], const char *url,
 	struct child_process *conn;
 	enum protocol protocol;
 	enum protocol_version version = get_protocol_version_config();
+	enum protocol_version max_version;
 
-	/*
-	 * NEEDSWORK: If we are trying to use protocol v2 and we are planning
-	 * to perform a push, then fallback to v0 since the client doesn't know
-	 * how to push yet using v2.
-	 */
-	if (version == protocol_v2 && !strcmp("git-receive-pack", prog))
-		version = protocol_v0;
+	max_version = determine_maximum_protocol_version(prog, version);
+	if (version > max_version)
+		version = max_version;
 
 	/* Without this we cannot rely on waitpid() to tell
 	 * what happened to our children.
diff --git a/protocol.c b/protocol.c
index 5e636785d1..1c553d8b99 100644
--- a/protocol.c
+++ b/protocol.c
@@ -79,3 +79,16 @@ enum protocol_version determine_protocol_version_client(const char *server_respo
 
 	return version;
 }
+
+enum protocol_version determine_maximum_protocol_version(
+		const char *service, enum protocol_version default_version)
+{
+	if (!strcmp(service, "git-receive-pack"))
+		return protocol_v1;
+	else if (!strcmp(service, "git-upload-archive"))
+		return protocol_v1;
+	else if (!strcmp(service, "git-upload-pack"))
+		return protocol_v2;
+
+	return default_version;
+}
diff --git a/protocol.h b/protocol.h
index 2ad35e433c..eabc0c5fab 100644
--- a/protocol.h
+++ b/protocol.h
@@ -31,4 +31,11 @@ extern enum protocol_version determine_protocol_version_server(void);
  */
 extern enum protocol_version determine_protocol_version_client(const char *server_response);
 
+/*
+ * Used by a client to determine the maximum protocol version to advertise for a
+ * particular service. If the service is unrecognized, return default_version.
+ */
+extern enum protocol_version determine_maximum_protocol_version(
+		const char *service, enum protocol_version default_version);
+
 #endif /* PROTOCOL_H */
diff --git a/remote-curl.c b/remote-curl.c
index fb28309e85..028adb76ae 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -344,6 +344,7 @@ static struct discovery *discover_refs(const char *service, int for_push)
 	int http_ret, maybe_smart = 0;
 	struct http_get_options http_options;
 	enum protocol_version version = get_protocol_version_config();
+	enum protocol_version max_version;
 
 	if (last && !strcmp(service, last->service))
 		return last;
@@ -360,13 +361,9 @@ static struct discovery *discover_refs(const char *service, int for_push)
 		strbuf_addf(&refs_url, "service=%s", service);
 	}
 
-	/*
-	 * NEEDSWORK: If we are trying to use protocol v2 and we are planning
-	 * to perform a push, then fallback to v0 since the client doesn't know
-	 * how to push yet using v2.
-	 */
-	if (version == protocol_v2 && !strcmp("git-receive-pack", service))
-		version = protocol_v0;
+	max_version = determine_maximum_protocol_version(service, version);
+	if (version > max_version)
+		version = max_version;
 
 	/* Add the extra Git-Protocol header */
 	if (get_protocol_http_header(version, &protocol_header))
-- 
2.19.0.605.g01d371f741-goog
Previous: Josh SteadmonNext: Stefan Beller
Message 2 of 52 in “Limit client version advertisements”
  1. 0/1 Limit client version advertisementsJosh Steadmon, Oct 2, 2018
  2. 1/1 protocol: limit max protocol version per serviceJosh Steadmon, Oct 2, 2018
  3. Stefan BellerOct 2, 2018
  4. Josh SteadmonOct 3, 2018
  5. Stefan BellerOct 3, 2018
  6. Josh SteadmonOct 5, 2018
  7. Stefan BellerOct 5, 2018
  8. Josh SteadmonOct 10, 2018
  9. Jonathan NiederOct 12, 2018
  10. Jonathan NiederOct 12, 2018
  11. Josh SteadmonOct 12, 2018
  12. Jonathan NiederOct 12, 2018
  13. Junio C HamanoOct 13, 2018
  14. 0/1 Advertise multiple supported proto versionssteadmon@google.com, Oct 12, 2018
  15. 1/1 protocol: advertise multiple supported versionssteadmon@google.com, Oct 12, 2018
  16. Stefan BellerOct 12, 2018
  17. Josh SteadmonOct 22, 2018
  18. Stefan BellerOct 23, 2018
  19. 0/1 Advertise multiple supported proto versionssteadmon@google.com, Nov 12, 2018
  20. 1/1 protocol: advertise multiple supported versionssteadmon@google.com, Nov 12, 2018
  21. Stefan BellerNov 12, 2018
  22. Re* [PATCH v3 1/1] protocol: advertise multiple supported versionsJunio C Hamano, Nov 13, 2018
  23. Stefan BellerNov 13, 2018
  24. Junio C HamanoNov 14, 2018
  25. Junio C HamanoNov 13, 2018
  26. Josh SteadmonNov 13, 2018
  27. Junio C HamanoNov 14, 2018
  28. Josh SteadmonNov 14, 2018
  29. Junio C HamanoNov 16, 2018
  30. Josh SteadmonNov 16, 2018
  31. Junio C HamanoNov 13, 2018
  32. SZEDER GáborNov 13, 2018
  33. Josh SteadmonNov 13, 2018
  34. SZEDER GáborNov 14, 2018
  35. Junio C HamanoNov 14, 2018
  36. SZEDER GáborNov 14, 2018
  37. 0/1 Advertise multiple supported proto versionsJosh Steadmon, Nov 14, 2018
  38. 1/1 protocol: advertise multiple supported versionsJosh Steadmon, Nov 14, 2018
  39. Junio C HamanoNov 14, 2018
  40. Josh SteadmonNov 14, 2018
  41. Junio C HamanoNov 16, 2018
  42. 0/1 Advertise multiple supported proto versionsJosh Steadmon, Nov 16, 2018
  43. 1/1 protocol: advertise multiple supported versionsJosh Steadmon, Nov 16, 2018
  44. Ævar Arnfjörð BjarmasonDec 14, 2018
  45. Josh SteadmonDec 14, 2018
  46. Ævar Arnfjörð BjarmasonDec 14, 2018
  47. Josh SteadmonDec 18, 2018
  48. 0/1 Advertise multiple supported proto versionsJosh Steadmon, Dec 20, 2018
  49. 1/1 protocol: advertise multiple supported versionsJosh Steadmon, Dec 20, 2018
  50. Jonathan TanFeb 5, 2019
  51. Josh SteadmonFeb 7, 2019
  52. Jonathan TanFeb 11, 2019

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.