Report

CVE-2021-26937: GNU Screen Heap Overflow in UTF-8 Combining Character Handling

21b335c1-429b-4324-a839-34d09cf05b4e

GNU Screen v4.8.0 contains a heap buffer overflow vulnerability (CVE-2021-26937) in the utf8_handle_comb() function in src/encoding.c. The function manages a dynamic array of combining character entries with fixed sentinel entries at indices 0x800 and 0x801 that control loop iteration bounds via their c1/c2 fields. When processing UTF-8 combining characters, user-controlled values can corrupt these root entries' c2 fields, causing subsequent loop iterations to access heap memory far beyond the allocated 0x802-element array, resulting in information disclosure and potential code execution.",antml:parameter> Investigation methodology: (1) Located source at src/encoding.c:1010-1072; (2) Identified heap allocation at line 1019: combchars = calloc(0x802, sizeof(struct combchar *)); (3) Found root sentinel initialization at lines 1032-1039 with c2 bounds of 0x700 (normal) and 0x800 (double-byte); (4) Traced vulnerable write at line 1068: combchars[i]->c2 = c; where 'c' is user-controlled combining character value; (5) Identified that if index i can be manipulated to be 0x800 or 0x801, the root entry's loop bound is corrupted; (6) Observed that the check at line 1053 (if i == 0x800 || i == 0x801) is insufficient to prevent corruption through linked list pointer manipulation in comb_tofront(); (7) Found call site in ansi.c:523 where utf8_handle_comb receives untrusted combining character input.",antml:parameter> The vulnerability arises from insufficient bounds checking on array index i when writing to combchars[i]->c2. The root cause is that the root sentinel entries at 0x800 and 0x801 are not protected from modification via the combchars[i] = value pattern. Exploitation requires: (1) Sending multiple UTF-8 combining characters to fill the array; (2) Manipulating the linked list structure via comb_tofront() to corrupt the prev/next pointers; (3) Causing i to be set to a root index despite the check at line 1053; (4) Writing a large combining character value as the c2 bound; (5) Triggering the loop at line 1042 in the next call, which now iterates to the corrupted large bound, causing heap overflow. The fix requires adding explicit validation that i < 0x800 before the vulnerable write at lines 1067-1068, or moving root entries outside the dynamically-allocated array.",antml:parameter> Vulnerability confirmed by: (1) Code analysis showing no bounds check between assignment and root entry indices; (2) Proof-of-concept file heap_overflow_poc.c in the repository explicitly describing the attack; (3) The check at line 1053 can be bypassed because it only returns if conditions are met, but the prior state of combchars array can be manipulated through comb_tofront before reaching the check; (4) Allocation size (0x802) only provides valid indices 0-0x801, but loop iteration with corrupted c2 can exceed this.",antml:parameter> version_mismatch