Package: gbdfed
Version: 1.6-6
Severity: normal
Tags: upstream

Hello,

I experienced a segfault in gbdfed while opening a font that contains a
character with a large codepoint ("ENCODING"). I have experimentally determined
that this happens with values greater/equal 150'000.

Here's an example file (crash.bdf):

8<---------------------------------
STARTFONT 2.1
FONT a
SIZE 11 75 75
FONTBOUNDINGBOX 5 8 0 -1
STARTPROPERTIES 0
ENDPROPERTIES
CHARS 1

STARTCHAR thing
ENCODING 150000
SWIDTH 436 0
DWIDTH 5 0
BBX 5 8 0 -1
BITMAP
00
00
00
00
00
00
ENDCHAR
8<---------------------------------

Here's an abridged GDB session:

$ gdb --args gbdfed crash.bdf
Reading symbols from gbdfed...
Downloading separate debug info for /usr/bin/gbdfed
Reading symbols from 
/home/jn/.cache/debuginfod_client/003746153518d9047e8fe77773982444a2470f5f/debuginfo...
(gdb) dir gbdfed-1.6/
Source directories searched: 
/home/jn/dev/cccac/rgb/busdisplay/crash/gbdfed-1.6:$cdir:$cwd
(gdb) r
Starting program: /usr/bin/gbdfed crash.bdf
Downloading 47.93 K separate debug info for system-supplied DSO at 
0x7ffff7fc1000
...
[New Thread 0x7ffff628f6c0 (LWP 4173232)]
[New Thread 0x7ffff5a8e6c0 (LWP 4173233)]
[New Thread 0x7ffff528d6c0 (LWP 4173234)]

Thread 1 "gbdfed" received signal SIGSEGV, Segmentation fault.
0x0000555555564452 in _bdf_parse_glyphs (line=0x7ffffffeb815 "ENCODING", 
linelen=<optimized out>, lineno=10,
    call_data=<optimized out>, client_data=0x7fffffffb800) at ./bdf.c:1377
⚠️ warning: Source file is more recent than executable.
1377                if (_bdf_glyph_modified(p->have, p->glyph_enc)) {
(gdb) x/3i $pc
=> 0x555555564452 <_bdf_parse_glyphs+370>:      mov    (%rbx,%rax,4),%edx
   0x555555564455 <_bdf_parse_glyphs+373>:      test   %esi,%edx
   0x555555564457 <_bdf_parse_glyphs+375>:      jne    0x555555564758 
<_bdf_parse_glyphs+1144>
(gdb) p p
$1 = (_bdf_parse_t *) 0x7fffffffb800
(gdb) i r rbx rax edx
rbx            0x7fffffffb800      140737488336896
rax            0x1267              4711
edx            0xfffdb610          -150000
(gdb) p *p
$2 = {
  flags = 111,
  cnt = 1,
  row = 0,
  bpr = 0,
  minlb = 32767,
  maxlb = 0,
  maxrb = 0,
  maxas = 0,
  maxds = 0,
  rbearing = 0,
  glyph_name = 0x555555636410 "thing",
  glyph_enc = 150000,
  font = 0x5555556603a0,
  opts = 0x5555555d6284 <options+132>,
  client_data = 0x0,
  callback = 0x0,
  cb = {
    reason = 0,
    current = 0,
    total = 0,
    errlineno = 0
  },
  have = {0 <repeats 2048 times>},
  list = {
    field = 0x55555565ca60,
    size = 10,
    used = 2,
    bfield = 0x0,
    bsize = 0,
    bused = 0
  }
}
(gdb) list
1372            /*
1373             * Check to see if this encoding has already been encountered.  
If it
1374             * has then change it to unencoded so it gets added if 
indicated.
1375             */
1376            if (p->glyph_enc >= 0) {
1377                if (_bdf_glyph_modified(p->have, p->glyph_enc)) {    // 
<---- crashed here
1378                    /*
1379                     * Add a message saying a glyph has been moved to the
1380                     * unencoded area.
1381                     */
1382                    sprintf(nbuf, ACMSG12, p->glyph_enc, p->glyph_name);
1383                    _bdf_add_acmsg(font, nbuf, strlen(nbuf));
1384                    p->glyph_enc = -1;
1385                    font->modified = 1;
1386                } else
1387                  _bdf_set_glyph_modified(p->have, p->glyph_enc);
1388            }
1389    
1390            if (p->glyph_enc >= 0) {
1391                /*
(gdb)

bdfP.h contains this definition:

  #define _bdf_glyph_modified(map, e) ((map)[(e) >> 5] & (1 << ((e) & 31)))

p->have is defined in bdf.c / typedef _bdf_parse_t as:

  unsigned int have[2048];

which covers 2048 * 32 = 65536 bit elements. Any access beyond that point can't
be safe, but there doesn't appear to be a bounds check. The previously
determined limit of 150'000 probably depends on the memory layout.
&p->have[150000 >> 5] just happens to be just above 0x800000000000 on my
system, which makes it an invalid (non-canonical) address on x86_64.


Best regards,
J. Neuschäfer


-- System Information:
Debian Release: forky/sid
  APT prefers stable-security
  APT policy: (500, 'stable-security'), (500, 'testing'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 6.12.57+deb13-amd64 (SMP w/12 CPU threads; PREEMPT)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages gbdfed depends on:
ii  libc6                2.42-6
ii  libfreetype6         2.13.3+dfsg-1
ii  libgdk-pixbuf-2.0-0  2.44.4+dfsg-1
ii  libglib2.0-0t64      2.86.3-1
ii  libgtk2.0-0t64       2.24.33-10
ii  libpango-1.0-0       1.56.3-2
ii  libx11-6             2:1.8.12-1

gbdfed recommends no packages.

gbdfed suggests no packages.

-- no debconf information

Reply via email to