#1144169 nec2c: stack buffer overflow reading a card line longer than 81 characters

Package:
nec2c
Source:
nec2c
Description:
Translation of the NEC2 FORTRAN source code to the C language
Submitter:
ch
Date:
2026-08-14 16:27:02 UTC
Severity:
normal
Tags:
#1144169#5
Date:
2026-08-11 22:04:32 UTC
From:
To:
main() reads deck lines into an 81-byte buffer, while load_line() fills a
caller's buffer with up to LINE_LEN (132) characters plus a terminator:

  main.c:41   char ain[3], line_buf[81];
  nec2c.h:81  #define LINE_LEN 132
  misc.c      while( num_chr < LINE_LEN ) { buff[num_chr++] = (char)chr; ... }
              buff[num_chr] = '\0';

A card line longer than 81 characters therefore overflows line_buf by up to 52
bytes. A NEC-2 comment card is 80 columns plus its "CM ", so ordinary input
reaches it; no malformed or hostile deck is required.

Reproducer -- a deck whose second CM card is 100 characters. It must not be
the first line, which is read on a different path:

  {
    echo "CM first"
    echo "CM $(printf 'A%.0s' {1..100})"
    echo "CE"
    echo "GW 1 9 0 0 0 0 0 1 0.001"
    echo "GE 0"
    echo "EK"
    echo "EX 0 1 5 0 1.0 0.0"
    echo "FR 0 1 0 0 145.9 0"
    echo "RP 0 3 1 1000 0 0 30 0"
    echo "EN"
  } > t.nec
  nec2c -i t.nec -o t.out

Built from the 1.3.1-3 source with gcc -O0 -g -fsanitize=address:

  ERROR: AddressSanitizer: stack-buffer-overflow
  WRITE of size 1
    #0 load_line misc.c:154
    #1 main      main.c:269
  [1920, 2001) 'line_buf' (line 41) <== Memory access at offset 2001
    overflows this variable

The packaged binary usually does not crash, because main()'s infile[81] and
otfile[81] are adjacent to line_buf and absorb the overrun rather than the
stack canary. That makes it quiet, not harmless: it is an out-of-bounds write
whose length is controlled by the input file.

Severity: this is a local command-line tool reading a file the user chose, so
I have not filed it as a security issue. It would deserve one for any workflow
that feeds it decks from an untrusted source.

Upstream status: upstream git (https://github.com/KJ7LNW/nec2c) widened the
buffer to LINE_LEN in 3d8c230, before tagging v1.3.1. That reduces the
overflow to a single byte but does not remove it -- load_line() still writes
buff[LINE_LEN] into a char[LINE_LEN] -- and I have reported that separately.
There is therefore no released upstream version to upgrade to yet.

Suggested fix, which is sufficient on its own against the 1.3.1-3 source:

#1144169#10
Date:
2026-08-14 09:24:53 UTC
From:
To:
Thanks, I'll get on this later!
#1144169#15
Date:
2026-08-14 16:24:59 UTC
From:
To:
I filed an issue upstream:
https://github.com/KJ7LNW/nec2c/issues/2