Package: libslang2
Version: 2.3.0-3+b1
Severity: important
Tags: patch
Hello,
We are having issues in the debian installer when running the installer
menu inside screen on the serial console. This boils down to running the
following program:
#include <slang.h>
#include <newt.h>
int main(void) {
SLang_init_tty(0, 1, 0);
newtInit();
SLang_init_tty(0, 1, 0);
newtInit();
}
inside screen. The gdb backtrace shows:
#0 0x00007ffff75088c4 in __GI___libc_free (mem=0x60206d) at malloc.c:2965
#1 0x00007ffff7b265c2 in SLfree (p=0x60206d "DO\t\033[%dB") at
./src/slcommon.c:187
#2 0x00007ffff7a9298b in _pSLtt_tifreeent (t=0x601fe0) at ./src/sltermin.c:256
#3 0x00007ffff7a985f9 in SLtt_initialize (term=0x7fffffffd48f "screen") at
./src/sldisply.c:2604
#4 0x00007ffff7a98379 in SLtt_get_terminfo () at ./src/sldisply.c:2532
#5 0x00007ffff7838ef8 in newtInit () at newt.c:877
#6 0x000000000040067c in main () at test.c:8
_pSLtt_tifreeent(256) is:
SLfree ((char *)t->string_table);
and indeed when TERMCAP is set, string_table is set inside tcap_getent:
ti->string_table = (char *) b;
where b is *inside* an allocation, and thus the subsequent SLfree will
crash. I have attached a patch which makes one allocation per string,
as _pSLtt_tifreeent expects, which thus fixes the issue.
Samuel
-- System Information:
Debian Release: stretch/sid
APT prefers unstable-debug
APT policy: (500, 'unstable-debug'), (500, 'buildd-unstable'), (500,
'unstable'), (500, 'testing'), (500, 'stable'), (500, 'oldstable'), (1,
'experimental-debug'), (1, 'buildd-experimental'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 4.7.0 (SMP w/4 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
Versions of packages libslang2 depends on:
ii libc6 2.23-5
libslang2 recommends no packages.
libslang2 suggests no packages.
-- no debconf information
--
Samuel
"...very few phenomena can pull someone out of Deep Hack Mode, with two
noted exceptions: being struck by lightning, or worse, your *computer*
being struck by lightning."
(By Matt Welsh)
--- a/src/sltermin.c
+++ b/src/sltermin.c
@@ -546,13 +546,10 @@ static int tcap_getent (SLCONST char *te
if (NULL == (buf = (unsigned char *) SLmalloc (ulen)))
return -1;
- b = buf;
-
/* The beginning of the termcap entry contains the names of the entry.
* It is terminated by a colon.
*/
- ti->terminal_names = (char *) b;
t = termcap;
len = tcap_extract_field (t);
if (len < 0)
@@ -560,9 +557,9 @@ static int tcap_getent (SLCONST char *te
SLfree ((char *)buf);
return -1;
}
- strncpy ((char *) b, (char *) t, (unsigned int) len);
- b[len] = 0;
- b += len + 1;
+ ti->terminal_names = SLmalloc (len + 1);
+ strncpy (ti->terminal_names, (char *) t, (unsigned int) len);
+ ti->terminal_names[len] = 0;
ti->name_section_size = len;
/* Now, we are really at the start of the termcap entries. Point the
@@ -571,7 +568,7 @@ static int tcap_getent (SLCONST char *te
termcap = t + (len + 1);
/* Process strings first. */
- ti->string_table = (char *) b;
+ b = buf;
t = termcap;
while (-1 != (len = tcap_extract_field (t)))
{
@@ -597,6 +594,7 @@ static int tcap_getent (SLCONST char *te
t = (unsigned char *) _pSLexpand_escaped_char ((char *) t,
(char *) tmax, &wch, NULL);
if (t == NULL)
{
+ SLfree (ti->terminal_names);
SLfree ((char *)buf);
return -1;
}
@@ -617,12 +615,14 @@ static int tcap_getent (SLCONST char *te
/* skip colon to next field. */
t++;
}
- ti->string_table_size = (int) (b - (unsigned char *) ti->string_table);
+ ti->string_table_size = (int) (b - buf);
+ ti->string_table = SLmalloc (ti->string_table_size);
+ memcpy (ti->string_table, buf, ti->string_table_size);
/* Now process the numbers. */
t = termcap;
- ti->numbers = b;
+ b = buf;
while (-1 != (len = tcap_extract_field (t)))
{
unsigned char *b1;
@@ -647,11 +647,13 @@ static int tcap_getent (SLCONST char *te
b1[2] = (unsigned char) len; /* replace the # by the length */
t++;
}
- ti->num_numbers = (b - ti->numbers);
+ ti->num_numbers = (b - buf);
+ ti->numbers = SLmalloc (ti->num_numbers);
+ memcpy (ti->numbers, buf, ti->num_numbers);
/* Now process the flags. */
t = termcap;
- ti->boolean_flags = b;
+ b = buf;
while (-1 != (len = tcap_extract_field (t)))
{
/* We are looking for: XX#NUMBER */
@@ -665,8 +667,11 @@ static int tcap_getent (SLCONST char *te
t += 3;
b += 2;
}
- ti->boolean_section_size = (b - ti->boolean_flags);
+ ti->boolean_section_size = (b - buf);
+ ti->boolean_flags = SLmalloc (ti->boolean_section_size);
+ memcpy (ti->boolean_flags, buf, ti->boolean_section_size);
ti->flags = SLTERMCAP;
+ SLfree ((char *)buf);
return 0;
}