Skip to content

unicode:characters_to_list/binary return an uninitialized term for a non-chardata argument #2446

Open

Description

@bettio

Found while reviewing #2357; pre-existing (same behaviour on release-0.7 at 18b3587). BEAM raises badarg, AtomVM returns an {error, _, Rest} tuple whose Rest is an uninitialized stack value:

unicode:characters_to_list(id(foo))         %% BEAM badarg   AtomVM {error,[],<garbage>}
unicode:characters_to_binary(id({1, 2}))    %% BEAM badarg   AtomVM {error,<<>>,<garbage>}
unicode:characters_to_list(id(<<1:1>>))     %% same, once #2357 makes non-byte-aligned bitstrings possible

erlang:display/1 prints the third element as Unknown term type: 129947828638076, and valgrind reports "Conditional jump or move depends on uninitialised value(s)" in term_is_tuple and memory_shallow_copy_term as soon as the tuple is printed or copied by the GC, so a process keeping the result can crash the VM. A non-chardata element inside a list ([foo]) is correctly rejected with badarg; only the top-level argument is affected.

Cause: interop_chardata_fold (src/libAtomVM/interop.c:252-258) returns InteropBadArg for a top-level term that is neither a binary nor a list before rest_fun is ever called, so *rest is never written. interop_chardata_to_bytes maps that result to UnicodeError (the badarg flag is only set by rest_fun), and nif_unicode_characters_to_list (src/libAtomVM/nifs.c:7278-7279) and nif_unicode_characters_to_binary (:7339-7340) build the result tuple with the uninitialized rest.

Fix: validate argv[0] with term_is_list(t) || term_is_binary(t) in the two NIFs and raise badarg otherwise, or have interop_chardata_fold report the top-level term through rest_fun so that interop_chardata_to_bytes_size and interop_chardata_to_bytes return UnicodeBadArg

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions