Module Name: src Committed By: christos Date: Thu Sep 9 20:25:30 UTC 2021
Modified Files: src/lib/libedit: readline.c Log Message: fix memory issues found by fuzzing (double frees and buffer overflows) To generate a diff of this commit: cvs rdiff -u -r1.165 -r1.166 src/lib/libedit/readline.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libedit/readline.c diff -u src/lib/libedit/readline.c:1.165 src/lib/libedit/readline.c:1.166 --- src/lib/libedit/readline.c:1.165 Fri Sep 3 08:20:38 2021 +++ src/lib/libedit/readline.c Thu Sep 9 16:25:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.165 2021/09/03 12:20:38 christos Exp $ */ +/* $NetBSD: readline.c,v 1.166 2021/09/09 20:25:30 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include "config.h" #if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: readline.c,v 1.165 2021/09/03 12:20:38 christos Exp $"); +__RCSID("$NetBSD: readline.c,v 1.166 2021/09/09 20:25:30 christos Exp $"); #endif /* not lint && not SCCSID */ #include <sys/types.h> @@ -624,8 +624,7 @@ get_history_event(const char *cmd, int * if (sub) { if (pat != last_search_pat) { - if (last_search_pat) - el_free(last_search_pat); + el_free(last_search_pat); last_search_pat = pat; } ret = history_search(pat, -1); @@ -642,9 +641,8 @@ get_history_event(const char *cmd, int * } if (sub && len) { - if (last_search_match && last_search_match != pat) - el_free(last_search_match); - last_search_match = pat; + el_free(last_search_match); + last_search_match = strdup(pat); } if (pat != last_search_pat) @@ -676,7 +674,7 @@ getfrom(const char **cmdp, char **fromp, for (; *cmd && *cmd != delim; cmd++) { if (*cmd == '\\' && cmd[1] == delim) cmd++; - if (len >= size) { + if (len - 1 >= size) { char *nwhat; nwhat = el_realloc(what, (size <<= 1) * sizeof(*nwhat)); if (nwhat == NULL) { @@ -707,6 +705,7 @@ getfrom(const char **cmdp, char **fromp, } if (!*cmd) { el_free(what); + *fromp = NULL; return -1; } @@ -715,6 +714,7 @@ getfrom(const char **cmdp, char **fromp, if (!*cmd) { el_free(what); + *fromp = NULL; return -1; } return 1; @@ -728,6 +728,7 @@ getto(const char **cmdp, char **top, con size_t from_len = strlen(from); const char *cmd = *cmdp; char *with = el_realloc(*top, size * sizeof(*with)); + *top = NULL; if (with == NULL) goto out; @@ -848,7 +849,7 @@ _history_expand_command(const char *comm /* Now parse any word designators */ if (*cmd == '%') /* last word matched by ?pat? */ - tmp = strdup(last_search_match? last_search_match:""); + tmp = strdup(last_search_match ? last_search_match : ""); else if (strchr("^*$-0123456789", *cmd)) { start = end = -1; if (*cmd == '^') @@ -928,26 +929,30 @@ _history_expand_command(const char *comm continue; /*FALLTHROUGH*/ case 's': - delim = *(++cmd), cmd++; /* XXX: check */ - if ((ev = getfrom(&cmd, &from, search, delim)) != 1) { - el_free(tmp); - return ev; - } - if ((ev = getto(&cmd, &to, from, delim)) != 1) { - el_free(tmp); - return ev; - } + ev = -1; + delim = *++cmd; + if (delim == '\0' || *++cmd == '\0') + goto out; + if ((ev = getfrom(&cmd, &from, search, delim)) != 1) + goto out; + if ((ev = getto(&cmd, &to, from, delim)) != 1) + goto out; aptr = _rl_compat_sub(tmp, from, to, g_on); if (aptr) { el_free(tmp); tmp = aptr; } g_on = 0; + cmd--; continue; } } *result = tmp; return p_on ? 2 : 1; +out: + el_free(tmp); + return ev; + }