Skip to content

intuition: cut STRINGA_TextVal to the gadget's MaxChars - #1927

Merged
Kalamatee merged 2 commits into
aros-development-team:masterfrom
tomaszstaniak:intuition-strgclass-textval-bound
Oct 30, 2026
Merged

Kalamatee merged 2 commits into
aros-development-team:masterfrom
tomaszstaniak:intuition-strgclass-textval-bound

Conversation

@tomaszstaniak

Copy link
Copy Markdown
Contributor

Problem

strgclass copies STRINGA_TextVal into the gadget's edit buffer with strcpy(), both at OM_NEW and at OM_SET. The buffer holds STRINGA_MaxChars bytes including the terminating NUL, whether the class allocated it or the caller passed it with STRINGA_Buffer. A text of MaxChars characters or more is therefore written past the end of the buffer.

asl.library creates its file requester's pattern, drawer and file gadgets this way; the pattern gadget has MaxChars 257 and gets ASLFR_InitialPattern as its initial text. A program that opens a file requester with a longer pattern (for example a long list of file name extensions) overwrites the memory after that buffer. On pc-x86_64 a requester with a 300-character pattern ended in an "Illegal instruction" Software Failure in Kickstart code when it was closed. On the native Raspberry Pi system the next allocation stopped with "TLSF free-list corruption at REMOVE_HEADER", and the damaged block header held bytes of the pattern. This was found with VectorCraft, whose Open pattern lists many formats.

Change

rom/intuition/strgclass.c: a small helper copies the text and cuts it to MaxChars - 1 characters, the same limit set_buffer_str() already applies to STRINGA_LongVal. OM_NEW and OM_SET use it instead of strcpy(). Texts that fit are stored exactly as before. If MaxChars is not positive the buffer is left alone.

New test developer/debug/test/intuition/strgtextval (added to the directory's mmakefile): for texts of 0, 5, 15, 16 and 300 characters it creates a gadget with STRINGA_Buffer, STRINGA_MaxChars 16 and the text as STRINGA_TextVal, sets the text again with SetAttrs(), and checks that STRINGA_TextVal returns the caller's buffer, that the stored length is min(length, 15) and that the guard bytes after the buffer are untouched. The guard area is longer than the longest text, so the unfixed class is detected without damaging other memory.

Tests run

pc-x86_64, GCC 10.5 mainline toolchain. The base package (aros-base.pkg, which contains intuition.library) was built in a separate build directory from master d68c0a7 (before) and with this change (after), and booted through extra GRUB entries on a mainline system installed from 9802c8c (the only intuition change between the two is in dogadgetmethoda.c; strgclass.c and asl.library are the same). QEMU, TCG.

run strgtextval ASL requester, 12-character pattern ASL requester, 300-character pattern
installed system (9802c8c) 0, 5, 15 characters pass; 16 and 300 characters overwrite the guard at OM_NEW and OM_SET (FAIL) file name typed, OK, results returned Software Failure (Illegal instruction in Kickstart code) after OK
base package from master d68c0a7 same as the installed system not run not run
base package with this change all 10 checks pass file name typed, OK, results returned file name typed, OK; fr_Pattern is the first 256 characters; 2000 allocations afterwards complete

The test program was also built in the tree (make test-intuition) without warnings.

raspi-aarch64: the changed strgclass.c compiles without warnings with the Clang 20.1 AROS toolchain against the native Pi SDK (object file only, intuition.library was not linked), and the test compiles. Neither was run with the change. Before the change, the test printed FAIL for the long text on the native Pi system (2026-08-22 image). i386, arm and m68k were not built.

strgclass copied STRINGA_TextVal into the edit buffer with strcpy(), at OM_NEW and at OM_SET. The buffer holds MaxChars bytes including the terminating NUL (allocated by the class, or given with STRINGA_Buffer), so a text of MaxChars characters or more was written past its end.

asl.library hands the file requester's pattern to such a gadget with MaxChars 257. A program that opened a file requester with a longer ASLFR_InitialPattern (a long list of file name extensions) damaged the memory after that buffer. On pc-x86_64 a 300-character pattern ended in an "Illegal instruction" Software Failure in Kickstart code once the requester was closed; on the native Raspberry Pi system the next allocation stopped with "TLSF free-list corruption at REMOVE_HEADER", and the damaged block header held bytes of the pattern.

The text is now cut to MaxChars - 1 characters, as STRINGA_LongVal already is. Texts that fit are stored as before.

Test: developer/debug/test/intuition/strgtextval creates gadgets with STRINGA_Buffer and MaxChars 16, followed by guard bytes, for texts of 0, 5, 15, 16 and 300 characters, sets each text again with SetAttrs(), and checks the stored length and the guard bytes.
@Kalamatee

Copy link
Copy Markdown
Member
  • Use memmove() instead of memcpy(), because some programs pass the gadget's own buffer back in. The old strcpy() had the same overlap problem, so it isn't a regression.
  • Give the existing set_buffer_str() the same MaxChars <= 0 guard. Without it, MaxChars == 0 writes Buffer[-1] and calls memcpy() with a huge length. That bug predates this PR.
  • In the test, strlen() is compared with an int, which can trigger a signed/unsigned warning.

@tomaszstaniak

Copy link
Copy Markdown
Contributor Author

Addressed in 0ed67ed. TextVal now uses memmove(), and set_buffer_str() returns without writing when MaxChars <= 0. The test uses a size_t-compatible comparison for strlen() and a size_t array index; the class-name arguments also have the type expected by NewObject().

Added gadget tests for passing the existing buffer back, passing an overlapping suffix, and MaxChars values -1, 0 and 1 for both TextVal and LongVal at OM_NEW and OM_SET. The invalid-capacity LongVal tests can crash an unfixed class, which is noted in the test source.

Host ASan/UBSan checks using the helper bodies extracted from strgclass.c detect overlapping memcpy and a negative copy length before this change; both checks pass afterwards. The extended gadget test builds and links for x86_64 ABIv1 and ABIv11 with -Wall -Wextra -Werror. The updated strgclass.c also compiles to an x86_64 v1 object, with existing pointer-sign warnings in the module and its headers. I have not rebuilt and booted intuition.library or run the extended gadget test on AROS for this revision; the earlier native results in the description apply to b75e72e.

@Kalamatee
Kalamatee merged commit 91cb9f4 into aros-development-team:master Oct 30, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants