This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Fix crash in "help memory read"
ClosedPublic

Authored by DavidSpickett on Jan 18 2021, 8:02 AM.

Details

Summary

When a command option does not have a short version
(e.g. -f for --file), we use an arbitrary value in the
short_option field to mark it as invalid.
(though this value is unqiue to be used later for other
things)

We check that this short option is valid to print using
llvm::isPrint. This implicitly casts our int to char,
meaning we check the last char of any short_option value.

Since the arbitrary value we chose for these options is
some shortened hex version of the name, this returned true
even for invalid values.

Since llvm::isPrint returns true we later call std::islower
and/or std::isupper on the short_option value. (the int)

Calling these functions with something that cannot be validly
converted to unsigned char is undefined. Somehow we got/get
away with this but for me compiling with g++-9 I got a crash
for "help memory read".

The other command that uses this is "target variable" but that
didn't crash for unknown reasons.

Checking that short_option can fit into an unsigned char before
we call llvm::isPrint means we will not attempt to call islower/upper
on these options since we have no reason to print them.

This also fixes bogus short options being shown for "memory read"
and target variable.

For "target variable", before:

-e <filename> ( --file <filename> )
-b <filename> ( --shlib <filename> )

After:

--file <filename>
--shlib <filename>

(note that the bogus short options are just the bottom byte of our
arbitrary short_option value)

Diff Detail

Event Timeline

DavidSpickett requested review of this revision.Jan 18 2021, 8:02 AM
DavidSpickett created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptJan 18 2021, 8:02 AM

UBSAN might have caught this if we had a test that took this path but I need to confirm that. If so I could add some more as a smoke test of sorts, or just call help on every command if that's not going to take an age.

See lldb/source/Interpreter/OptionGroupOutputFile.cpp and lldb/source/Commands/CommandObjectTarget.cpp for two uses of these arbitrary short_option values. The calls to islower/upper are in lldb/source/Interpreter/Options.cpp Options::GenerateOptionUsage.

labath accepted this revision.Jan 18 2021, 11:23 PM
labath added inline comments.
lldb/include/lldb/Utility/OptionDefinition.h
53

Something like llvm::is(U)Int<CHAR_BIT>(short_option) would better convey the intention.

This revision is now accepted and ready to land.Jan 18 2021, 11:23 PM
This revision was landed with ongoing or failed builds.Jan 19 2021, 1:54 AM
This revision was automatically updated to reflect the committed changes.
DavidSpickett marked an inline comment as done.Jan 19 2021, 1:54 AM

From what I understand this means D91378 is no longer necessary. thanks!