URL: <https://savannah.gnu.org/bugs/?68555>
Summary: [PATCH] [troff] ASAN runtime error: 1-byte heap
overread in `print_hyphenation_exceptions_request()`
Group: GNU roff
Submitter: gbranden
Submitted: Fri 24 Jul 2026 07:16:37 AM UTC
Category: Core
Severity: 4 - Important
Item Group: Crash/Unresponsive
Status: In Progress
Privacy: Public
Assigned to: gbranden
Open/Closed: Open
Discussion Lock: Unlocked
Planned Release: None
_______________________________________________________
Follow-up Comments:
-------------------------------------------------------
Date: Fri 24 Jul 2026 07:16:37 AM UTC By: G. Branden Robinson <gbranden>
Illustration with instrumented function.
My code for dumping hyphenation exception words didn't properly handle the
case where the exception word has no hyphenation points at all. (It issued a
correct _report_, but read one byte too far while doing so.)
$ ../src/roff/groff/tests/phw-request-works.sh
baz-qux
tab-le
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
word=imagemagick
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=0, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=1, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=2, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=3, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=4, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=5, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=6, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=7, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=8, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=9, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=10, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=11, hypoint is not null
image-magick *
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
word=xviiith
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=0, hypoint is not null
troff:<standard input>:6: debug: GBR: print_hyphenation_exceptions_request:
i=1, hypoint is not null
=================================================================
==30964==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x6020000d0971 at pc 0x55f01f0aaad2 bp 0x7fff495510b0 sp 0x7fff495510a8
READ of size 1 at 0x6020000d0971 thread T0
#0 0x55f01f0aaad1 in print_hyphenation_exceptions_request
../src/roff/troff/env.cpp:4196
#1 0x55f01f0ae135 in request::invoke(symbol, bool)
../src/roff/troff/input.cpp:3921
#2 0x55f01f0bffff in interpolate_macro_or_invoke_request
../src/roff/troff/input.cpp:4755
#3 0x55f01f0c9ca1 in process_input_stack()
../src/roff/troff/input.cpp:3649
#4 0x55f01f0de526 in process_input_file ../src/roff/troff/input.cpp:9948
#5 0x55f01f0ed58e in main ../src/roff/troff/input.cpp:10319
#6 0x7f868028bd79 in __libc_start_main ../csu/libc-start.c:308
#7 0x55f01f03e7e9 in _start
(/home/branden/src/GIT/groff/build/troff+0xbe7e9)
0x6020000d0971 is located 0 bytes to the right of 1-byte region
[0x6020000d0970,0x6020000d0971)
allocated by thread T0 here:
#0 0x7f86808127a7 in operator new[](unsigned long)
../../../../src/libsanitizer/asan/asan_new_delete.cpp:102
#1 0x55f01f07bac6 in hyphen_trie::insert_hyphenation(dictionary*, char
const*, int) ../src/roff/troff/env.cpp:4331
#2 0x55f01f07bac6 in hyphen_trie::interpret_patterns_file(char const*,
bool, dictionary*) ../src/roff/troff/env.cpp:4574
SUMMARY: AddressSanitizer: heap-buffer-overflow ../src/roff/troff/env.cpp:4196
in print_hyphenation_exceptions_request
Shadow bytes around the buggy address:
0x0c04800120d0: fa fa 01 fa fa fa 02 fa fa fa 01 fa fa fa 03 fa
0x0c04800120e0: fa fa 02 fa fa fa 02 fa fa fa 01 fa fa fa 01 fa
0x0c04800120f0: fa fa 02 fa fa fa 03 fa fa fa 02 fa fa fa 03 fa
0x0c0480012100: fa fa 03 fa fa fa 02 fa fa fa 04 fa fa fa 02 fa
0x0c0480012110: fa fa 02 fa fa fa 01 fa fa fa 01 fa fa fa 03 fa
=>0x0c0480012120: fa fa 01 fa fa fa 01 fa fa fa 01 fa fa fa[01]fa
0x0c0480012130: fa fa 01 fa fa fa 01 fa fa fa 01 fa fa fa 02 fa
0x0c0480012140: fa fa 02 fa fa fa 02 fa fa fa 03 fa fa fa fd fd
0x0c0480012150: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
0x0c0480012160: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
0x0c0480012170: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
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
Shadow gap: cc
==30964==ABORTING
I have a fix.
$ git diff src/roff/
diff --git a/src/roff/troff/env.cpp b/src/roff/troff/env.cpp
index 5b2cbaf7c..e8d3ed1c8 100644
--- a/src/roff/troff/env.cpp
+++ b/src/roff/troff/env.cpp
@@ -4189,6 +4189,7 @@ static void print_hyphenation_exceptions_request() //
.phw
(void) memset(wordbuf, '\0', bufsz);
size_t i = 0, j = 0, len = word.length();
bool is_mode_dependent = false;
+ if (*hypoint != 0) {
while (i < len) {
if ((hypoint != 0 /* nullptr */) && (*hypoint == i)) {
wordbuf[j++] = '-';
@@ -4203,6 +4204,7 @@ static void print_hyphenation_exceptions_request() //
.phw
}
wordbuf[j++] = word[i++];
}
+ }
errprint("%1", wordbuf);
if (is_mode_dependent)
errprint("\t*");
Indentation will need to be updated. And as a bonus this change avoids
unnecessary work...not like the `phw` request is a hot path, though.
_______________________________________________________
Reply to this item at:
<https://savannah.gnu.org/bugs/?68555>
_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
signature.asc
Description: PGP signature
