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;
 }
 

Reply via email to