summaryrefslogtreecommitdiff
path: root/shell.c
diff options
context:
space:
mode:
authorTaylor Blau <me@ttaylorr.com>2022-10-06 20:00:04 -0400
committerTaylor Blau <me@ttaylorr.com>2022-10-06 20:00:04 -0400
commitf64d4ca8d65bdca39da444d24bde94864ac01bb1 (patch)
treeedc9055c3dc8e378474c951ad6a3513deaa777d0 /shell.c
parent3dcec76d9df911ed8321007b1d197c1a206dc164 (diff)
parent83d5e3341b69b3116675f13d2fab208a12c79e27 (diff)
Sync with 2.37.4
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Diffstat (limited to 'shell.c')
-rw-r--r--shell.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/shell.c b/shell.c
index 811e13b9c9..7ff4109db7 100644
--- a/shell.c
+++ b/shell.c
@@ -47,6 +47,8 @@ static void cd_to_homedir(void)
die("could not chdir to user's home directory");
}
+#define MAX_INTERACTIVE_COMMAND (4*1024*1024)
+
static void run_shell(void)
{
int done = 0;
@@ -67,22 +69,46 @@ static void run_shell(void)
run_command_v_opt(help_argv, RUN_SILENT_EXEC_FAILURE);
do {
- struct strbuf line = STRBUF_INIT;
const char *prog;
char *full_cmd;
char *rawargs;
+ size_t len;
char *split_args;
const char **argv;
int code;
int count;
fprintf(stderr, "git> ");
- if (git_read_line_interactively(&line) == EOF) {
+
+ /*
+ * Avoid using a strbuf or git_read_line_interactively() here.
+ * We don't want to allocate arbitrary amounts of memory on
+ * behalf of a possibly untrusted client, and we're subject to
+ * OS limits on command length anyway.
+ */
+ fflush(stdout);
+ rawargs = xmalloc(MAX_INTERACTIVE_COMMAND);
+ if (!fgets(rawargs, MAX_INTERACTIVE_COMMAND, stdin)) {
fprintf(stderr, "\n");
- strbuf_release(&line);
+ free(rawargs);
break;
}
- rawargs = strbuf_detach(&line, NULL);
+ len = strlen(rawargs);
+
+ /*
+ * If we truncated due to our input buffer size, reject the
+ * command. That's better than running bogus input, and
+ * there's a good chance it's just malicious garbage anyway.
+ */
+ if (len >= MAX_INTERACTIVE_COMMAND - 1)
+ die("invalid command format: input too long");
+
+ if (len > 0 && rawargs[len - 1] == '\n') {
+ if (--len > 0 && rawargs[len - 1] == '\r')
+ --len;
+ rawargs[len] = '\0';
+ }
+
split_args = xstrdup(rawargs);
count = split_cmdline(split_args, &argv);
if (count < 0) {