daemon: use cld->env_array when re-spawning

This avoids an ugly strcat into a fixed-size buffer. It's not wrong (the buffer is plenty large enough for an IPv6 address plus some minor formatting), but it takes some effort to verify that. Unfortunately we are still stuck with some fixed-size buffers to hold the output of inet_ntop. But at least we now pass very easy-to-verify parameters, rather than doing a manual computation to account for other data in the buffer. As a side effect, this also fixes the case where we might pass an uninitialized portbuf buffer through the environment. This probably couldn't happen in practice, as it would mean that addr->sa_family was neither AF_INET nor AF_INET6 (and that is all we are listening on). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Sep 24, 2015 at 17:08 UTC f063d38b808e184675e5b0931ea0167a013b3fcb
1 file changed +10 -16
daemon.c
+10 -16
@@ -811,8 +811,6 @@ static char **cld_argv;
811 static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
812 {
813 struct child_process cld = CHILD_PROCESS_INIT;
814 - char addrbuf[300] = "REMOTE_ADDR=", portbuf[300];
815 - char *env[] = { addrbuf, portbuf, NULL };
814
815 if (max_connections && live_children >= max_connections) {
816 kill_some_child();
@@ -826,27 +824,23 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
824 }
825
826 if (addr->sa_family == AF_INET) {
827 + char buf[128] = "";
828 struct sockaddr_in *sin_addr = (void *) addr;
830 - inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf + 12,
831 - sizeof(addrbuf) - 12);
832 - snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
833 - ntohs(sin_addr->sin_port));
829 + inet_ntop(addr->sa_family, &sin_addr->sin_addr, buf, sizeof(buf));
830 + argv_array_pushf(&cld.env_array, "REMOTE_ADDR=%s", buf);
831 + argv_array_pushf(&cld.env_array, "REMOTE_PORT=%d",
832 + ntohs(sin_addr->sin_port));
833 #ifndef NO_IPV6
834 } else if (addr->sa_family == AF_INET6) {
835 + char buf[128] = "";
836 struct sockaddr_in6 *sin6_addr = (void *) addr;
837 -
838 - char *buf = addrbuf + 12;
839 - *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
840 - inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf,
841 - sizeof(addrbuf) - 13);
842 - strcat(buf, "]");
843 -
844 - snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
845 - ntohs(sin6_addr->sin6_port));
837 + inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(buf));
838 + argv_array_pushf(&cld.env_array, "REMOTE_ADDR=[%s]", buf);
839 + argv_array_pushf(&cld.env_array, "REMOTE_PORT=%d",
840 + ntohs(sin6_addr->sin6_port));
841 #endif
842 }
843
849 - cld.env = (const char **)env;
844 cld.argv = (const char **)cld_argv;
845 cld.in = incoming;
846 cld.out = dup(incoming);