[bug #68447] Possible buffer overflow in lexer input

"Dmitri A. Sergatskov" <[email protected]> Sat, 13 Jun 2026 01:08:47 -0400 (EDT)
Newsgroups gmane.comp.gnu.octave.bugs
Message-ID <[email protected]>
Please use the bug tracker to post updates to a bug report.  The mailing list is intended as a read-only notification stream.  Info posted to this mailing list address won't appear in the tracker database where it is most useful.

URL:
  <https://savannah.gnu.org/bugs/?68447>

                 Summary: Possible buffer overflow in lexer input
                   Group: GNU Octave
               Submitter: dasergatskov
               Submitted: Sat 13 Jun 2026 05:08:42 AM UTC
                Category: Octave Function
                Severity: 3 - Normal
                Priority: 5 - Normal
              Item Group: Segfault, Bus Error, etc.
                  Status: None
             Assigned to: None
         Originator Name:
        Originator Email:
             Open/Closed: Open
         Discussion Lock: Unlocked
                 Release: dev
        Operating System: Any
           Fixed Release: None
         Planned Release: None


    _______________________________________________________

Follow-up Comments:


-------------------------------------------------------
Date: Sat 13 Jun 2026 05:08:42 AM UTC By: Dmitri A. Sergatskov <dasergatskov>
Pasting a very long (looks to me > 16K char length, but I have not narrowed it
down) line at Octave prompt causing some memory problem. 
I did the following:

octave:1> a = randi(127, 1,3000,"uint8");
octave:2> save -ascii  a.txt

Then in the shell `wl-copy < a.txt` (copy the file into copy/paste buffer,
there are other ways to do it). and then Shift-Ctr-V to Octave prompt. In the
Octave compiled with normal flags, it paste OK but then it segfault at exit,
in the Octave compiled with ASAN I see:

000000e+01 1.00000000e+01 5.60000000e+01 9.30000000e+01 1.03000000e+02
7.90000000e+01 1.13000000e+02 3.50000000e+01 1.19000000e+02 4.40000000e+01
1.00000000e+00 4.00000000e+01 4.40000000e+01
=================================================================
==290006==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x7d9c9895b202 at pc 0x0000004d1212 bp 0x7b0bb6d43b90 sp 0x7b0bb6d43350
WRITE of size 45001 at 0x7d9c9895b202 thread T10 (QThread)
    #0 0x0000004d1211 in __asan_memcpy
(/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-gui+0x4d1211)
(BuildId: 41d3d37cf373ad6184ebd05b208a7b644fa7aa3c)
    #1 0x7f0ca20595b7 in octave::base_lexer::input_buffer::copy_chunk(char*,
unsigned long, bool)
/home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/lex.ll:2497:3
    #2 0x7f0ca20522a5 in yy_get_next_buffer(void*)
/home/dmitri/src/dev/octave/clang_asan/libinterp/parse-tree/lex.cc:3846:3
    #3 0x7f0ca201b564 in octave_lex(OCTAVE_STYPE*, void*)
/home/dmitri/src/dev/octave/clang_asan/libinterp/parse-tree/lex.cc:3685:17
    #4 0x7f0ca20a722f in
octave::push_parser::run(std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char>> const&, bool)
/home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/oct-parse.yy:5248:20
    #5 0x7f0ca206ce35 in octave::push_parser::run()
/home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/oct-parse.yy:5334:21
    #6 0x7f0ca211b216 in octave::tree_evaluator::repl()
/home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:809:38
    #7 0x7f0ca32652f0 in octave::interpreter::main_loop()
/home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:1373:22
    #8 0x7f0ca32652f0 in octave::interpreter::execute()
/home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:903:27
    #9 0x7f0ca6b43457 in octave::interpreter_qobject::execute()
/home/dmitri/src/dev/octave/clang_asan/../libgui/src/interpreter-qobject.cc:81:32
    #10 0x7f0ca47807dd in QObject::event(QEvent*)
(/lib64/libQt6Core.so.6+0x1807dd) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #11 0x7f0ca5a3f92d in QApplicationPrivate::notify_helper(QObject*,
QEvent*) (/lib64/libQt6Widgets.so.6+0x3f92d) (BuildId:
48825f73e2823661bfcd464c2ff4bad17f14e159)
    #12 0x7f0ca6c39981 in octave::octave_qapplication::notify(QObject*,
QEvent*)
/home/dmitri/src/dev/octave/clang_asan/../libgui/src/octave-qobject.cc:153:28
    #13 0x7f0ca470f7b7 in QCoreApplication::notifyInternal2(QObject*, QEvent*)
(/lib64/libQt6Core.so.6+0x10f7b7) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #14 0x7f0ca4713c08 in QCoreApplicationPrivate::sendPostedEvents(QObject*,
int, QThreadData*) (/lib64/libQt6Core.so.6+0x113c08) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #15 0x7f0ca4a6a57e  (/lib64/libQt6Core.so.6+0x46a57e) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #16 0x7f0c9cca8f23  (/lib64/libglib-2.0.so.0+0x43f23) (BuildId:
3f6b90ef1994781e46eff4c43d40f0d9016943bf)
    #17 0x7f0c9ccad037  (/lib64/libglib-2.0.so.0+0x48037) (BuildId:
3f6b90ef1994781e46eff4c43d40f0d9016943bf)
    #18 0x7f0c9ccad1e2 in g_main_context_iteration
(/lib64/libglib-2.0.so.0+0x481e2) (BuildId:
3f6b90ef1994781e46eff4c43d40f0d9016943bf)
    #19 0x7f0ca4a69a9c in
QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)
(/lib64/libQt6Core.so.6+0x469a9c) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #20 0x7f0ca471d57a in
QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)
(/lib64/libQt6Core.so.6+0x11d57a) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #21 0x7f0ca4850e09 in QThread::exec() (/lib64/libQt6Core.so.6+0x250e09)
(BuildId: 224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #22 0x7f0ca490ce8e  (/lib64/libQt6Core.so.6+0x30ce8e) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #23 0x0000004d0d9a in asan_thread_start(void*) asan_interceptors.cpp.o
    #24 0x7f0c9d079d18 in start_thread (/lib64/libc.so.6+0x72d18) (BuildId:
18472003bbf1c5f098a09b5016b9b8bd4c7c59f0)
    #25 0x7f0c9d0fd64b in __GI___clone3 (/lib64/libc.so.6+0xf664b) (BuildId:
18472003bbf1c5f098a09b5016b9b8bd4c7c59f0)

0x7d9c9895b202 is located 0 bytes after 16386-byte region
[0x7d9c98957200,0x7d9c9895b202)
allocated by thread T10 (QThread) here:
    #0 0x0000004d3588 in malloc
(/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-gui+0x4d3588)
(BuildId: 41d3d37cf373ad6184ebd05b208a7b644fa7aa3c)
    #1 0x7f0ca2052d8b in octave_alloc(unsigned long, void*)
/home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/lex.ll:1935:10
    #2 0x7f0ca2052d8b in octave__create_buffer(_IO_FILE*, int, void*)
/home/dmitri/src/dev/octave/clang_asan/libinterp/parse-tree/lex.cc:4154:26
    #3 0x7f0ca2052d8b in octave_restart(_IO_FILE*, void*)
/home/dmitri/src/dev/octave/clang_asan/libinterp/parse-tree/lex.cc:4083:13
    #4 0x7f0ca20184f9 in octave::base_lexer::reset()
/home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/lex.ll:2575:5
    #5 0x7f0ca209e8d5 in octave::base_parser::reset()
/home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/oct-parse.yy:2491:11
    #6 0x7f0ca211b059 in octave::tree_evaluator::repl()
/home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:801:24
    #7 0x7f0ca32652f0 in octave::interpreter::main_loop()
/home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:1373:22
    #8 0x7f0ca32652f0 in octave::interpreter::execute()
/home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:903:27
    #9 0x7f0ca6b43457 in octave::interpreter_qobject::execute()
/home/dmitri/src/dev/octave/clang_asan/../libgui/src/interpreter-qobject.cc:81:32
    #10 0x7f0ca47807dd in QObject::event(QEvent*)
(/lib64/libQt6Core.so.6+0x1807dd) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #11 0x7f0ca5a3f92d in QApplicationPrivate::notify_helper(QObject*,
QEvent*) (/lib64/libQt6Widgets.so.6+0x3f92d) (BuildId:
48825f73e2823661bfcd464c2ff4bad17f14e159)
    #12 0x7f0ca6c39981 in octave::octave_qapplication::notify(QObject*,
QEvent*)
/home/dmitri/src/dev/octave/clang_asan/../libgui/src/octave-qobject.cc:153:28
    #13 0x7f0ca470f7b7 in QCoreApplication::notifyInternal2(QObject*, QEvent*)
(/lib64/libQt6Core.so.6+0x10f7b7) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #14 0x7f0ca4713c08 in QCoreApplicationPrivate::sendPostedEvents(QObject*,
int, QThreadData*) (/lib64/libQt6Core.so.6+0x113c08) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #15 0x7f0ca4a6a57e  (/lib64/libQt6Core.so.6+0x46a57e) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #16 0x7f0c9cca8f23  (/lib64/libglib-2.0.so.0+0x43f23) (BuildId:
3f6b90ef1994781e46eff4c43d40f0d9016943bf)
    #17 0x7f0c9ccad037  (/lib64/libglib-2.0.so.0+0x48037) (BuildId:
3f6b90ef1994781e46eff4c43d40f0d9016943bf)
    #18 0x7f0c9ccad1e2 in g_main_context_iteration
(/lib64/libglib-2.0.so.0+0x481e2) (BuildId:
3f6b90ef1994781e46eff4c43d40f0d9016943bf)
    #19 0x7f0ca4a69a9c in
QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)
(/lib64/libQt6Core.so.6+0x469a9c) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #20 0x7f0ca471d57a in
QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)
(/lib64/libQt6Core.so.6+0x11d57a) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #21 0x7f0ca4850e09 in QThread::exec() (/lib64/libQt6Core.so.6+0x250e09)
(BuildId: 224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #22 0x7f0ca490ce8e  (/lib64/libQt6Core.so.6+0x30ce8e) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #23 0x0000004d0d9a in asan_thread_start(void*) asan_interceptors.cpp.o

Thread T10 (QThread) created by T0 here:
    #0 0x0000004b6b65 in pthread_create
(/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-gui+0x4b6b65)
(BuildId: 41d3d37cf373ad6184ebd05b208a7b644fa7aa3c)
    #1 0x7f0ca490c9e4 in QThread::start(QThread::Priority)
(/lib64/libQt6Core.so.6+0x30c9e4) (BuildId:
224e4c3e7b152d40184b9dcab80ca362f85f24ca)
    #2 0x7f0ca6c3bee8 in octave::base_qobject::start_main_thread()
/home/dmitri/src/dev/octave/clang_asan/../libgui/src/octave-qobject.cc:482:18
    #3 0x7f0ca6c3bee8 in
octave::base_qobject::base_qobject(octave::qt_application&, bool)
/home/dmitri/src/dev/octave/clang_asan/../libgui/src/octave-qobject.cc:342:3
    #4 0x7f0ca6c73e2b in octave::qt_application::execute()
/home/dmitri/src/dev/octave/clang_asan/../libgui/src/qt-application.cc:97:16
    #5 0x000000519a17 in main
/home/dmitri/src/dev/octave/clang_asan/../src/main-gui.cc:159:17
    #6 0x7f0c9d00a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680)
(BuildId: 18472003bbf1c5f098a09b5016b9b8bd4c7c59f0)
    #7 0x7f0c9d00a797 in __libc_start_main@GLIBC_2.2.5
(/lib64/libc.so.6+0x3797) (BuildId: 18472003bbf1c5f098a09b5016b9b8bd4c7c59f0)
    #8 0x00000042d4d4 in _start
(/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-gui+0x42d4d4)
(BuildId: 41d3d37cf373ad6184ebd05b208a7b644fa7aa3c)

SUMMARY: AddressSanitizer: heap-buffer-overflow
(/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-gui+0x4d1211)
(BuildId: 41d3d37cf373ad6184ebd05b208a7b644fa7aa3c) in __asan_memcpy
Shadow bytes around the buggy address:
  0x7d9c9895af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7d9c9895b000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7d9c9895b080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7d9c9895b100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7d9c9895b180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7d9c9895b200:[02]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7d9c9895b280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7d9c9895b300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7d9c9895b380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7d9c9895b400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7d9c9895b480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==290006==ABORTING


The diff seems to fix this for me:

@@ -2483,9 +2483,12 @@
   if (by_lines)
     {
       std::size_t newline_pos = m_buffer.find ('\n', m_offset);
-      len = (newline_pos != std::string::npos
-             ? newline_pos - m_offset + 1
-             : (max_size > m_chars_left ? m_chars_left : max_size));
+      std::size_t line_len = m_chars_left;
+
+      if (newline_pos != std::string::npos)
+        line_len = newline_pos - m_offset + 1;
+
+      len = std::min (line_len, max_size);
     }
   else
     len = max_size > m_chars_left ? m_chars_left : max_size;

(It could be written differently, but just I do not like ternaries)

Dmitri.
-- 








    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?68447>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
signature.asc (application/pgp-signature, 228 B)
-----BEGIN PGP SIGNATURE-----

iHUEABYIAB0WIQQk97aszIMMAvLLwm6qLAuaBUf3TgUCaizl3wAKCRCqLAuaBUf3
TstwAP46yG9cu//UW7YQGNMZugkLHkYSsS0VCRt6D8UlUqgZpAEA+hrovXqvDX87
7DsY4r6WRwMuD2/d59zIkgjc6o8mXgg=
=f1NP
-----END PGP SIGNATURE-----