ul: Fix buffer overflow

The text-utility ul can run into a buffer overflow on very long lines.
See this proof of concept how to reproduce the issue:

$ dd if=/dev/zero bs=1M count=10 | tr '\000' '\041' > poc.txt
$ echo -ne '\xe\x5f\x8\x5f\x61\x2\xf\x5f\x8\x5f' | dd of=poc.txt conv=notrunc
$ ul -i poc.txt > /dev/null # output would take ages
Segmentation fault
$ _

The problem manifests by using alloca with "maxcol", which can be as
large as INT_MAX, based on the input line.

A very long line (> 8 MB) with modes must be supplied to ul, as seen in
my proof of concept byte sequence above.

It is rather easy to fix this issue: allocate space on the heap instead.
maxcol could overflow here, but in that case no system will have enough
space to handle the request, properly ending ul through an err() call.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
This commit is contained in:
Tobias Stoeckmann 2016-09-08 21:19:22 +02:00 committed by Karel Zak
parent 0b404f0845
commit f20b214edc
1 changed files with 4 additions and 10 deletions

View File

@ -402,11 +402,7 @@ static void flushln(void)
static void overstrike(void)
{
register int i;
#ifdef __GNUC__
register wchar_t *lbuf = __builtin_alloca((maxcol + 1) * sizeof(wchar_t));
#else
wchar_t lbuf[BUFSIZ];
#endif
register wchar_t *lbuf = xmalloc((maxcol + 1) * sizeof(wchar_t));
register wchar_t *cp = lbuf;
int hadbold=0;
@ -439,16 +435,13 @@ static void overstrike(void)
for (cp = lbuf; *cp; cp++)
putwchar(*cp == '_' ? ' ' : *cp);
}
free(lbuf);
}
static void iattr(void)
{
register int i;
#ifdef __GNUC__
register wchar_t *lbuf = __builtin_alloca((maxcol+1)*sizeof(wchar_t));
#else
wchar_t lbuf[BUFSIZ];
#endif
register wchar_t *lbuf = xmalloc((maxcol + 1) * sizeof(wchar_t));
register wchar_t *cp = lbuf;
for (i = 0; i < maxcol; i++)
@ -465,6 +458,7 @@ static void iattr(void)
*cp = 0;
fputws(lbuf, stdout);
putwchar('\n');
free(lbuf);
}
static void initbuf(void)