@matheusbsbs / matheus-bagliano / commits / 2ff4d1ab9e
Fork 0

receive-pack: do not send error details to the client

If the objects that a client pushes to the server cannot be processed for any reason, an error is reported back to the client via the git protocol. We used to send quite detailed information if a system call failed if unpack-objects is run. This can be regarded as an information leak. Now we do not send any error details like we already do in the case where index-pack failed. Errors in system calls as well as the exit code of unpack-objects and index-pack are now reported to stderr; in the case of a local push or via ssh these messages still go to the client, but that is OK since these forms of access to the server assume that the client can be trusted. If receive-pack is run from git-daemon, then the daemon should put the error messages into the syslog. With this reasoning a new status report is added for the post-update-hook; untrusted (i.e. daemon's) clients cannot observe its status anyway, others may want to know failure details. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Sixt committed Jun 21, 2009 at 23:16 UTC 2ff4d1ab9ef6660c88020ddaadc410157e130cdc
1 file changed +22 -31
builtin-receive-pack.c
+22 -31
@@ -123,27 +123,27 @@ static struct command *commands;
123 static const char pre_receive_hook[] = "hooks/pre-receive";
124 static const char post_receive_hook[] = "hooks/post-receive";
125
126 -static int hook_status(int code, const char *hook_name)
126 +static int run_status(int code, const char *cmd_name)
127 {
128 switch (code) {
129 case 0:
130 return 0;
131 case -ERR_RUN_COMMAND_FORK:
132 - return error("hook fork failed");
132 + return error("fork of %s failed", cmd_name);
133 case -ERR_RUN_COMMAND_EXEC:
134 - return error("hook execute failed");
134 + return error("execute of %s failed", cmd_name);
135 case -ERR_RUN_COMMAND_PIPE:
136 - return error("hook pipe failed");
136 + return error("pipe failed");
137 case -ERR_RUN_COMMAND_WAITPID:
138 return error("waitpid failed");
139 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
140 return error("waitpid is confused");
141 case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
142 - return error("%s died of signal", hook_name);
142 + return error("%s died of signal", cmd_name);
143 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
144 - return error("%s died strangely", hook_name);
144 + return error("%s died strangely", cmd_name);
145 default:
146 - error("%s exited with error code %d", hook_name, -code);
146 + error("%s exited with error code %d", cmd_name, -code);
147 return -code;
148 }
149 }
@@ -174,7 +174,7 @@ static int run_receive_hook(const char *hook_name)
174
175 code = start_command(&proc);
176 if (code)
177 - return hook_status(code, hook_name);
177 + return run_status(code, hook_name);
178 for (cmd = commands; cmd; cmd = cmd->next) {
179 if (!cmd->error_string) {
180 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
@@ -186,7 +186,7 @@ static int run_receive_hook(const char *hook_name)
186 }
187 }
188 close(proc.in);
189 - return hook_status(finish_command(&proc), hook_name);
189 + return run_status(finish_command(&proc), hook_name);
190 }
191
192 static int run_update_hook(struct command *cmd)
@@ -203,7 +203,7 @@ static int run_update_hook(struct command *cmd)
203 argv[3] = sha1_to_hex(cmd->new_sha1);
204 argv[4] = NULL;
205
206 - return hook_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
206 + return run_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
207 RUN_COMMAND_STDOUT_TO_STDERR),
208 update_hook);
209 }
@@ -394,7 +394,7 @@ static char update_post_hook[] = "hooks/post-update";
394 static void run_update_post_hook(struct command *cmd)
395 {
396 struct command *cmd_p;
397 - int argc;
397 + int argc, status;
398 const char **argv;
399
400 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
@@ -417,8 +417,9 @@ static void run_update_post_hook(struct command *cmd)
417 argc++;
418 }
419 argv[argc] = NULL;
420 - run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
421 - | RUN_COMMAND_STDOUT_TO_STDERR);
420 + status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
421 + | RUN_COMMAND_STDOUT_TO_STDERR);
422 + run_status(status, update_post_hook);
423 }
424
425 static void execute_commands(const char *unpacker_error)
@@ -534,24 +535,10 @@ static const char *unpack(void)
535 unpacker[i++] = hdr_arg;
536 unpacker[i++] = NULL;
537 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
537 - switch (code) {
538 - case 0:
538 + if (!code)
539 return NULL;
540 - case -ERR_RUN_COMMAND_FORK:
541 - return "unpack fork failed";
542 - case -ERR_RUN_COMMAND_EXEC:
543 - return "unpack execute failed";
544 - case -ERR_RUN_COMMAND_WAITPID:
545 - return "waitpid failed";
546 - case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
547 - return "waitpid is confused";
548 - case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
549 - return "unpacker died of signal";
550 - case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
551 - return "unpacker died strangely";
552 - default:
553 - return "unpacker exited with error code";
554 - }
540 + run_status(code, unpacker[0]);
541 + return "unpack-objects abnormal exit";
542 } else {
543 const char *keeper[7];
544 int s, status, i = 0;
@@ -574,8 +561,11 @@ static const char *unpack(void)
561 ip.argv = keeper;
562 ip.out = -1;
563 ip.git_cmd = 1;
577 - if (start_command(&ip))
564 + status = start_command(&ip);
565 + if (status) {
566 + run_status(status, keeper[0]);
567 return "index-pack fork failed";
568 + }
569 pack_lockfile = index_pack_lockfile(ip.out);
570 close(ip.out);
571 status = finish_command(&ip);
@@ -583,6 +573,7 @@ static const char *unpack(void)
573 reprepare_packed_git();
574 return NULL;
575 }
576 + run_status(status, keeper[0]);
577 return "index-pack abnormal exit";
578 }
579 }