Skip to content

Commit 5fded84

Browse files
committed
git_connect: avoid full shell when executing git-upload-pack
When the `git-upload-pack` program is supposed to be called, we do not actually need to run this through a shell... This reduces the security surface of running Git on servers a bit. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent a4a5f67 commit 5fded84

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

connect.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,6 @@ struct child_process *git_connect(int fd[2], const char *url,
14591459
conn = git_connect_git(fd, hostandport, path, prog, version, flags);
14601460
conn->trace2_child_class = "transport/git";
14611461
} else {
1462-
struct strbuf cmd = STRBUF_INIT;
14631462
const char *const *var;
14641463

14651464
conn = xmalloc(sizeof(*conn));
@@ -1468,15 +1467,22 @@ struct child_process *git_connect(int fd[2], const char *url,
14681467
if (looks_like_command_line_option(path))
14691468
die(_("strange pathname '%s' blocked"), path);
14701469

1471-
strbuf_addstr(&cmd, prog);
1472-
strbuf_addch(&cmd, ' ');
1473-
sq_quote_buf(&cmd, path);
1470+
if (conn->args.nr == 0 && !does_cmd_require_shell(prog))
1471+
/* Trivial case: avoid running through shell */
1472+
strvec_pushl(&conn->args, prog, path, NULL);
1473+
else {
1474+
struct strbuf cmd = STRBUF_INIT;
1475+
strbuf_addstr(&cmd, prog);
1476+
strbuf_addch(&cmd, ' ');
1477+
sq_quote_buf(&cmd, path);
1478+
strvec_push_nodup(&conn->args, strbuf_detach(&cmd, NULL));
1479+
conn->use_shell = 1;
1480+
}
14741481

14751482
/* remove repo-local variables from the environment */
14761483
for (var = local_repo_env; *var; var++)
14771484
strvec_push(&conn->env, *var);
14781485

1479-
conn->use_shell = 1;
14801486
conn->in = conn->out = -1;
14811487
if (protocol == PROTO_SSH) {
14821488
char *ssh_host = hostandport;
@@ -1498,7 +1504,7 @@ struct child_process *git_connect(int fd[2], const char *url,
14981504
free(path);
14991505
child_process_clear(conn);
15001506
free(conn);
1501-
strbuf_release(&cmd);
1507+
strvec_clear(&conn->args);
15021508
return NULL;
15031509
}
15041510
conn->trace2_child_class = "transport/ssh";
@@ -1512,14 +1518,12 @@ struct child_process *git_connect(int fd[2], const char *url,
15121518
version);
15131519
}
15141520
}
1515-
strvec_push(&conn->args, cmd.buf);
15161521

15171522
if (start_command(conn))
15181523
die(_("unable to fork"));
15191524

15201525
fd[0] = conn->out; /* read from child's stdout */
15211526
fd[1] = conn->in; /* write to child's stdin */
1522-
strbuf_release(&cmd);
15231527
}
15241528
free(hostandport);
15251529
free(path);

0 commit comments

Comments
 (0)