Skip to content

Commit

Permalink
[NFC] Fix potential for use-after-free in DumpModuleInfoAction
Browse files Browse the repository at this point in the history
Since each `DumpModuleInfoAction` can now contain a pointer to a
`raw_ostream`, saving there a poiter that owned by a local `unique_ptr`
may cause use-after-free. Clarify ownership and save a `shared_ptr`
inside of `DumpModuleInfoAction` instead.
Found by static analyzer.

Reviewed By: tahonermann, aaron.ballman

Differential Revision: https://reviews.llvm.org/D146412
  • Loading branch information
Fznamznon committed Mar 30, 2023
1 parent efd34ba commit 42ae055
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 8 deletions.
6 changes: 4 additions & 2 deletions clang/include/clang/Frontend/FrontendActions.h
Expand Up @@ -177,9 +177,8 @@ class SyntaxOnlyAction : public ASTFrontendAction {
/// Dump information about the given module file, to be used for
/// basic debugging and discovery.
class DumpModuleInfoAction : public ASTFrontendAction {
public:
// Allow other tools (ex lldb) to direct output for their use.
llvm::raw_ostream *OutputStream = nullptr;
std::shared_ptr<llvm::raw_ostream> OutputStream;

protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
Expand All @@ -188,6 +187,9 @@ class DumpModuleInfoAction : public ASTFrontendAction {
void ExecuteAction() override;

public:
DumpModuleInfoAction() = default;
explicit DumpModuleInfoAction(std::shared_ptr<llvm::raw_ostream> Out)
: OutputStream(Out) {}
bool hasPCHSupport() const override { return false; }
bool hasASTFileSupport() const override { return true; }
bool hasIRSupport() const override { return false; }
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/Frontend/FrontendActions.cpp
Expand Up @@ -780,14 +780,12 @@ static StringRef ModuleKindName(Module::ModuleKind MK) {
void DumpModuleInfoAction::ExecuteAction() {
assert(isCurrentFileAST() && "dumping non-AST?");
// Set up the output file.
std::unique_ptr<llvm::raw_fd_ostream> OutFile;
CompilerInstance &CI = getCompilerInstance();
StringRef OutputFileName = CI.getFrontendOpts().OutputFile;
if (!OutputFileName.empty() && OutputFileName != "-") {
std::error_code EC;
OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str(), EC,
llvm::sys::fs::OF_TextWithCRLF));
OutputStream = OutFile.get();
OutputStream.reset(new llvm::raw_fd_ostream(
OutputFileName.str(), EC, llvm::sys::fs::OF_TextWithCRLF));
}
llvm::raw_ostream &Out = OutputStream ? *OutputStream : llvm::outs();

Expand Down
7 changes: 5 additions & 2 deletions lldb/source/Commands/CommandObjectTarget.cpp
Expand Up @@ -2179,8 +2179,11 @@ class CommandObjectTargetModulesDumpClangPCMInfo : public CommandObjectParsed {
const char *clang_args[] = {"clang", pcm_path};
compiler.setInvocation(clang::createInvocation(clang_args));

clang::DumpModuleInfoAction dump_module_info;
dump_module_info.OutputStream = &result.GetOutputStream().AsRawOstream();
// Pass empty deleter to not attempt to free memory that was allocated
// outside of the current scope, possibly statically.
std::shared_ptr<llvm::raw_ostream> Out(
&result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {});
clang::DumpModuleInfoAction dump_module_info(Out);
// DumpModuleInfoAction requires ObjectFilePCHContainerReader.
compiler.getPCHContainerOperations()->registerReader(
std::make_unique<clang::ObjectFilePCHContainerReader>());
Expand Down

0 comments on commit 42ae055

Please sign in to comment.