Skip to content

Commit 2ff4d1a

Browse files
j6tgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9462e3f commit 2ff4d1a

File tree

1 file changed

+22
-31
lines changed

1 file changed

+22
-31
lines changed

builtin-receive-pack.c

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -123,27 +123,27 @@ static struct command *commands;
123123
static const char pre_receive_hook[] = "hooks/pre-receive";
124124
static const char post_receive_hook[] = "hooks/post-receive";
125125

126-
static int hook_status(int code, const char *hook_name)
126+
static int run_status(int code, const char *cmd_name)
127127
{
128128
switch (code) {
129129
case 0:
130130
return 0;
131131
case -ERR_RUN_COMMAND_FORK:
132-
return error("hook fork failed");
132+
return error("fork of %s failed", cmd_name);
133133
case -ERR_RUN_COMMAND_EXEC:
134-
return error("hook execute failed");
134+
return error("execute of %s failed", cmd_name);
135135
case -ERR_RUN_COMMAND_PIPE:
136-
return error("hook pipe failed");
136+
return error("pipe failed");
137137
case -ERR_RUN_COMMAND_WAITPID:
138138
return error("waitpid failed");
139139
case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
140140
return error("waitpid is confused");
141141
case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
142-
return error("%s died of signal", hook_name);
142+
return error("%s died of signal", cmd_name);
143143
case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
144-
return error("%s died strangely", hook_name);
144+
return error("%s died strangely", cmd_name);
145145
default:
146-
error("%s exited with error code %d", hook_name, -code);
146+
error("%s exited with error code %d", cmd_name, -code);
147147
return -code;
148148
}
149149
}
@@ -174,7 +174,7 @@ static int run_receive_hook(const char *hook_name)
174174

175175
code = start_command(&proc);
176176
if (code)
177-
return hook_status(code, hook_name);
177+
return run_status(code, hook_name);
178178
for (cmd = commands; cmd; cmd = cmd->next) {
179179
if (!cmd->error_string) {
180180
size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
@@ -186,7 +186,7 @@ static int run_receive_hook(const char *hook_name)
186186
}
187187
}
188188
close(proc.in);
189-
return hook_status(finish_command(&proc), hook_name);
189+
return run_status(finish_command(&proc), hook_name);
190190
}
191191

192192
static int run_update_hook(struct command *cmd)
@@ -203,7 +203,7 @@ static int run_update_hook(struct command *cmd)
203203
argv[3] = sha1_to_hex(cmd->new_sha1);
204204
argv[4] = NULL;
205205

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 |
207207
RUN_COMMAND_STDOUT_TO_STDERR),
208208
update_hook);
209209
}
@@ -394,7 +394,7 @@ static char update_post_hook[] = "hooks/post-update";
394394
static void run_update_post_hook(struct command *cmd)
395395
{
396396
struct command *cmd_p;
397-
int argc;
397+
int argc, status;
398398
const char **argv;
399399

400400
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)
417417
argc++;
418418
}
419419
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);
422423
}
423424

424425
static void execute_commands(const char *unpacker_error)
@@ -534,24 +535,10 @@ static const char *unpack(void)
534535
unpacker[i++] = hdr_arg;
535536
unpacker[i++] = NULL;
536537
code = run_command_v_opt(unpacker, RUN_GIT_CMD);
537-
switch (code) {
538-
case 0:
538+
if (!code)
539539
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";
555542
} else {
556543
const char *keeper[7];
557544
int s, status, i = 0;
@@ -574,15 +561,19 @@ static const char *unpack(void)
574561
ip.argv = keeper;
575562
ip.out = -1;
576563
ip.git_cmd = 1;
577-
if (start_command(&ip))
564+
status = start_command(&ip);
565+
if (status) {
566+
run_status(status, keeper[0]);
578567
return "index-pack fork failed";
568+
}
579569
pack_lockfile = index_pack_lockfile(ip.out);
580570
close(ip.out);
581571
status = finish_command(&ip);
582572
if (!status) {
583573
reprepare_packed_git();
584574
return NULL;
585575
}
576+
run_status(status, keeper[0]);
586577
return "index-pack abnormal exit";
587578
}
588579
}

0 commit comments

Comments
 (0)