NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lib/60593: libedit: buffer overruns and arithmetic overflow
>Number: 60593
>Category: lib
>Synopsis: libedit: buffer overruns and arithmetic overflow
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Aug 14 22:35:00 +0000 2026
>Originator: Taylor R Campbell
>Release: current, 11, 10, 9
>Organization:
The NetBSD Editation, Inc.
>Environment:
>Description:
1. In libedit/readline.c getfrom, a 2021 fix for an off-by-one
error in a bounds check (to verify that there is space in the
buffer for len bytes plus a NUL byte) inadvertently turned it
into an off-by-two error in a bounds check:
693 char *what = el_realloc(*fromp, size * sizeof(*what));
...
699 for (; *cmd && *cmd != delim; cmd++) {
700 if (*cmd == '\\' && cmd[1] == delim)
701 cmd++;
=> 702 if (len - 1 >= size) {
703 char *nwhat;
704 nwhat = el_realloc(what, (size <<= 1) * sizeof(*nwhat));
705 if (nwhat == NULL) {
706 el_free(what);
707 el_free(*fromp);
708 *cmdp = cmd;
709 *fromp = NULL;
710 return 0;
711 }
712 what = nwhat;
713 }
714 what[len++] = *cmd;
715 }
716 what[len] = '\0';
https://nxr.netbsd.org/xref/src/lib/libedit/readline.c?r=1.184#687
The attempted fix was in rev. 1.166:
@@ -676,7 +674,7 @@ getfrom(const char **cmdp, char **fromp, const char *search, int delim)
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) {
Additionally, size << 1 (i.e., size * 2) could in principle
overflow; should verify size < SIZE_MAX/2/sizeof(*nwhat) before
computing (size << 1) * sizeof(*nwhat).
2. Possible three-wchar buffer overrun in vi mode searching:
73 el->el_search.patbuf = el_calloc(EL_BUFSIZ,
74 sizeof(*el->el_search.patbuf));
...
489 if (el->el_search.patbuf[0] != '.' &&
490 el->el_search.patbuf[0] != '*') {
491 (void) wcsncpy(tmpbuf, el->el_search.patbuf,
492 sizeof(tmpbuf) / sizeof(*tmpbuf) - 1);
493 el->el_search.patbuf[0] = '.';
494 el->el_search.patbuf[1] = '*';
495 (void) wcsncpy(&el->el_search.patbuf[2], tmpbuf,
496 EL_BUFSIZ - 3);
497 el->el_search.patlen++;
498 el->el_search.patbuf[el->el_search.patlen++] = '.';
499 el->el_search.patbuf[el->el_search.patlen++] = '*';
500 el->el_search.patbuf[el->el_search.patlen] = '\0';
501 }
https://nxr.netbsd.org/xref/src/lib/libedit/search.c?r=1.53#488
If, on input, the search already has a maximum-length patbuf
(and I see no way to rule this out), el->el_search.patlen++ may
advance past the end of the buffer.
Reported by Miroslav Lichvar <mlichvar%redhat.com@localhost>.
>How-To-Repeat:
code inspection
abuse^Wheavy use of interactive history editing or search features
>Fix:
1. Fix the bounds check by saying `+ 1' instead of `- 1', and
check for arithmetic overflow.
2. Fail if el->el_search.patlen >= EL_BUFSIZE - 3.
Home |
Main Index |
Thread Index |
Old Index