Skip to content

RawProps::at(name, prefix, suffix) leaves RawPropsParser a view of a destroyed key #59327

Open

Description

@YevheniiKotyrlo

Description

RawProps::at(name, prefix, suffix), which #57346 added back for callers that pass a prefix and a suffix apart, builds prefix + name + suffix in a local std::string and passes RawPropsParser::at a std::string_view of it (RawProps.cpp). While the parser is being prepared, it stores that view in keys_ (RawPropsParser.cpp), and the string is destroyed as RawProps::at returns. The next lookup's duplicate check compares against the stored view, and so does every lookup's cursor loop once the parser is ready. A props constructor that passes a prefix or a suffix therefore reads freed memory: the heap's for a key longer than std::string's inline buffer, a returned stack frame's for a shorter one.

No caller in this repository passes a prefix or a suffix, and Nitro's generated views pass nullptr for both, which the overload forwards to at(name).

Steps to reproduce

  1. In a react-native checkout at main, unpack the third-party sources ReactAndroid builds against: its prepareBoost, prepareDoubleConversion, prepareFastFloat, prepareFmt, prepareFolly and prepareGlog tasks write them to packages/react-native/ReactAndroid/build/third-party-ndk, as any ReactAndroid build does.
  2. Clone the reproducer and run its CC=clang CXX=clang++ ./run.sh <checkout> with a clang that has libc++. It compiles RawProps.cpp, RawPropsParser.cpp, RawPropsKeyMap.cpp and jsi under AddressSanitizer, with folly built as Fantom's tester builds it.
  3. main.cpp makes the two lookups a props constructor makes while its parser is prepared, at("Width", prefix, nullptr) and then at("Color", prefix, nullptr). With a prefix that puts the key on the heap, AddressSanitizer reports a heap-use-after-free in RawPropsParser::at; with border and detect_stack_use_after_return=1, a stack-use-after-return.

React Native Version

0.88.0

Affected Platforms

Other (please specify)

Output of npx @react-native-community/cli info

Not an app. The reproducer compiles ReactCommon from a react-native checkout at 79a562960d
(0.87.0 and 0.88.0 have the same RawProps::at), on Ubuntu 24.04.5 LTS with clang 21.1.8,
libc++ 21, CMake 3.28.3 and Ninja 1.11.1. ReactCommon is shared by Android and iOS.

Stacktrace or Logs

==877045==ERROR: AddressSanitizer: heap-use-after-free on address 0x6c82c09e0010 at pc 0x5624bcc650a6 bp 0x7ffd3d3309a0 sp 0x7ffd3d330148
READ of size 27 at 0x6c82c09e0010 thread T0
    …
    #5 0x5624bcd620de in facebook::react::RawPropsParser::at(facebook::react::RawProps const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>) const packages/react-native/ReactCommon/react/renderer/core/RawPropsParser.cpp:36:20
    #6 0x5624bcd5ecf0 in facebook::react::RawProps::at(char const*, char const*, char const*) const packages/react-native/ReactCommon/react/renderer/core/RawProps.cpp:138:19
    #7 0x5624bcd30937 in main main.cpp:22:12
    …
freed by thread T0 here:
    …
    #4 0x5624bcd5ed0c in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::~basic_string() <libc++>/string:1207:7
    #5 0x5624bcd5ed0c in facebook::react::RawProps::at(char const*, char const*, char const*) const packages/react-native/ReactCommon/react/renderer/core/RawProps.cpp:139:1
    #6 0x5624bcd30923 in main main.cpp:21:12
    …
previously allocated by thread T0 here:
    …
    #8 0x5624bcd5e944 in facebook::react::RawProps::at(char const*, char const*, char const*) const packages/react-native/ReactCommon/react/renderer/core/RawProps.cpp:131:16
    #9 0x5624bcd30923 in main main.cpp:21:12
    …
SUMMARY: AddressSanitizer: heap-use-after-free (rawprops_freed_key+0x6c0a5) (BuildId: 455eeab6b3b568f6efa9de9b34b3f5910f33230f) in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long)

==877057==ERROR: AddressSanitizer: stack-use-after-return on address 0x78b02dc00021 at pc 0x5c1bcb3c70a6 bp 0x7ffe1260aee0 sp 0x7ffe1260a688
READ of size 11 at 0x78b02dc00021 thread T0
    …
    #5 0x5c1bcb4c40de in facebook::react::RawPropsParser::at(facebook::react::RawProps const&, std::__1::basic_string_view<char, std::__1::char_traits<char>>) const packages/react-native/ReactCommon/react/renderer/core/RawPropsParser.cpp:36:20
    #6 0x5c1bcb4c0cf0 in facebook::react::RawProps::at(char const*, char const*, char const*) const packages/react-native/ReactCommon/react/renderer/core/RawProps.cpp:138:19
    …
SUMMARY: AddressSanitizer: stack-use-after-return (rawprops_freed_key+0x6c0a5) (BuildId: 455eeab6b3b568f6efa9de9b34b3f5910f33230f) in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long)

MANDATORY Reproducer

https://github.com/YevheniiKotyrlo/rawprops-prefixed-key-freed

Activity

  1. react-native-bot commented on Oct 21, 2026

    @react-native-bot
    Collaborator

    Warning

    Missing reproducer: We could not detect a reproducible example in your issue report. Reproducers are mandatory and we can accept only one of those as a valid reproducer:


    You can read more about about it on our website: How to report a bug.

  2. YevheniiKotyrlo commented on Oct 21, 2026

    @YevheniiKotyrlo
    ContributorAuthor

    The reproducer is now a repository, with the Gist's three files and a README: https://github.com/YevheniiKotyrlo/rawprops-prefixed-key-freed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs: AttentionIssues where the author has responded to feedback.Needs: ReproThis issue could be improved with a clear list of steps to reproduce the issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions