From 069bcda17d8194e9582c64dd4bc9dac99b015810 Mon Sep 17 00:00:00 2001 From: Michael Mann Date: Fri, 20 Jun 2025 23:05:00 -0400 Subject: [PATCH] Fix potential buffer overflows of interactive shell CVE-2025-6170 Fixes #941 --- shell.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/shell.c b/shell.c index 623cc77a..9b3a283e 100644 --- a/shell.c +++ b/shell.c @@ -41,6 +41,10 @@ #define STDIN_FILENO 0 #endif +#define MAX_PROMPT_SIZE 500 +#define MAX_ARG_SIZE 400 +#define MAX_COMMAND_SIZE 100 + /* * TODO: Improvement/cleanups for the XML shell * - allow to shell out an editor on a subpart @@ -1057,7 +1061,7 @@ xmllintShellPwd(xmllintShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer, */ static char * xmllintShellReadline(char *prompt) { - char buf[501]; + char buf[MAX_PROMPT_SIZE + 1]; char *ret; int len; @@ -1081,9 +1085,9 @@ xmllintShellReadline(char *prompt) { if (prompt != NULL) fprintf(stdout, "%s", prompt); fflush(stdout); - if (!fgets(buf, 500, stdin)) + if (!fgets(buf, MAX_PROMPT_SIZE, stdin)) return(NULL); - buf[500] = 0; + buf[MAX_PROMPT_SIZE] = 0; len = strlen(buf); ret = (char *) malloc(len + 1); if (ret != NULL) { @@ -1105,10 +1109,10 @@ xmllintShellReadline(char *prompt) { void xmllintShell(xmlDocPtr doc, const char *filename, FILE * output) { - char prompt[500] = "/ > "; + char prompt[MAX_PROMPT_SIZE] = "/ > "; char *cmdline = NULL, *cur; - char command[100]; - char arg[400]; + char command[MAX_COMMAND_SIZE]; + char arg[MAX_ARG_SIZE]; int i; xmllintShellCtxtPtr ctxt; #ifdef LIBXML_XPATH_ENABLED @@ -1165,7 +1169,8 @@ xmllintShell(xmlDocPtr doc, const char *filename, FILE * output) cur++; i = 0; while ((*cur != ' ') && (*cur != '\t') && - (*cur != '\n') && (*cur != '\r')) { + (*cur != '\n') && (*cur != '\r') && + (i < (MAX_COMMAND_SIZE - 1))) { if (*cur == 0) break; command[i++] = *cur++; @@ -1180,7 +1185,7 @@ xmllintShell(xmlDocPtr doc, const char *filename, FILE * output) while ((*cur == ' ') || (*cur == '\t')) cur++; i = 0; - while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) { + while ((*cur != '\n') && (*cur != '\r') && (*cur != 0) && (i < (MAX_ARG_SIZE - 1))) { if (*cur == 0) break; arg[i++] = *cur++; -- GitLab