Author: jmolenda Date: Thu Feb 18 18:05:17 2016 New Revision: 261280 URL: http://llvm.org/viewvc/llvm-project?rev=261280&view=rev Log: This patch stops lldb from loading a .lldbinit file from the current working directory by default -- a typical security problem that we need to be more conservative about.
It adds a new target setting, target.load-cwd-lldbinit which may be true (always read $cwd/.lldbinit), false (never read $cwd/.lldbinit) or warn (warn if there is a $cwd/.lldbinit and don't read it). The default is set to warn. If this is met with unhappiness, we can look at changing the default to true (to match current behavior) on a different platform. This does not affect reading of ~/.lldbinit - that will still be read, as before. If you run lldb in your home directory, it will not warn about the presence of a .lldbinit file there. I had to add two SB API - SBHostOS::GetUserHomeDirectory and SBFileSpec::AppendPathComponent - for the lldb driver code to be able to get the home directory path in an OS neutral manner. The warning text is There is a .lldbinit file in the current directory which is not being read. To silence this warning without sourcing in the local .lldbinit, add the following to the lldbinit file in your home directory: settings set target.load-cwd-lldbinit false To allow lldb to source .lldbinit files in the current working directory, set the value of this variable to true. Only do so if you understand and accept the security risk. <rdar://problem/24199163> Modified: lldb/trunk/include/lldb/API/SBFileSpec.h lldb/trunk/include/lldb/API/SBHostOS.h lldb/trunk/include/lldb/Target/Target.h lldb/trunk/scripts/interface/SBFileSpec.i lldb/trunk/scripts/interface/SBHostOS.i lldb/trunk/source/API/SBFileSpec.cpp lldb/trunk/source/API/SBHostOS.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/source/Target/Target.cpp lldb/trunk/tools/driver/Driver.cpp lldb/trunk/tools/driver/Driver.h Modified: lldb/trunk/include/lldb/API/SBFileSpec.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFileSpec.h?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBFileSpec.h (original) +++ lldb/trunk/include/lldb/API/SBFileSpec.h Thu Feb 18 18:05:17 2016 @@ -60,6 +60,9 @@ public: bool GetDescription (lldb::SBStream &description) const; + void + AppendPathComponent (const char *file_or_directory); + private: friend class SBAttachInfo; friend class SBBlock; Modified: lldb/trunk/include/lldb/API/SBHostOS.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBHostOS.h?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBHostOS.h (original) +++ lldb/trunk/include/lldb/API/SBHostOS.h Thu Feb 18 18:05:17 2016 @@ -28,6 +28,9 @@ public: static lldb::SBFileSpec GetLLDBPath (lldb::PathType path_type); + static lldb::SBFileSpec + GetUserHomeDirectory (); + static void ThreadCreated (const char *name); Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Thu Feb 18 18:05:17 2016 @@ -53,6 +53,13 @@ typedef enum LoadScriptFromSymFile eLoadScriptFromSymFileWarn } LoadScriptFromSymFile; +typedef enum LoadCWDlldbinitFile +{ + eLoadCWDlldbinitTrue, + eLoadCWDlldbinitFalse, + eLoadCWDlldbinitWarn +} LoadCWDlldbinitFile; + //---------------------------------------------------------------------- // TargetProperties //---------------------------------------------------------------------- @@ -192,6 +199,9 @@ public: LoadScriptFromSymFile GetLoadScriptFromSymbolFile() const; + LoadCWDlldbinitFile + GetLoadCWDlldbinitFile () const; + Disassembler::HexImmediateStyle GetHexImmediateStyle() const; Modified: lldb/trunk/scripts/interface/SBFileSpec.i URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBFileSpec.i?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/scripts/interface/SBFileSpec.i (original) +++ lldb/trunk/scripts/interface/SBFileSpec.i Thu Feb 18 18:05:17 2016 @@ -72,7 +72,10 @@ public: bool GetDescription (lldb::SBStream &description) const; - + + void + AppendPathComponent (const char *file_or_directory); + %pythoncode %{ def __get_fullpath__(self): spec_dir = self.GetDirectory() Modified: lldb/trunk/scripts/interface/SBHostOS.i URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBHostOS.i?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/scripts/interface/SBHostOS.i (original) +++ lldb/trunk/scripts/interface/SBHostOS.i Thu Feb 18 18:05:17 2016 @@ -22,6 +22,9 @@ public: static lldb::SBFileSpec GetLLDBPath (lldb::PathType path_type); + static lldb::SBFileSpec + GetUserHomeDirectory (); + static void ThreadCreated (const char *name); Modified: lldb/trunk/source/API/SBFileSpec.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFileSpec.cpp?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/source/API/SBFileSpec.cpp (original) +++ lldb/trunk/source/API/SBFileSpec.cpp Thu Feb 18 18:05:17 2016 @@ -211,3 +211,9 @@ SBFileSpec::GetDescription (SBStream &de strm.PutCString (path); return true; } + +void +SBFileSpec::AppendPathComponent (const char *fn) +{ + m_opaque_ap->AppendPathComponent (fn); +} Modified: lldb/trunk/source/API/SBHostOS.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBHostOS.cpp?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/source/API/SBHostOS.cpp (original) +++ lldb/trunk/source/API/SBHostOS.cpp Thu Feb 18 18:05:17 2016 @@ -17,6 +17,9 @@ #include "lldb/Host/HostThread.h" #include "lldb/Host/ThreadLauncher.h" +#include "llvm/Support/Path.h" +#include "llvm/ADT/SmallVector.h" + using namespace lldb; using namespace lldb_private; @@ -53,6 +56,19 @@ SBHostOS::GetLLDBPath (lldb::PathType pa return sb_fspec; } +SBFileSpec +SBHostOS::GetUserHomeDirectory () +{ + SBFileSpec sb_fspec; + + llvm::SmallString<64> home_dir_path; + llvm::sys::path::home_directory (home_dir_path); + FileSpec homedir (home_dir_path.c_str(), true); + + sb_fspec.SetFileSpec (homedir); + return sb_fspec; +} + lldb::thread_t SBHostOS::ThreadCreate ( Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Thu Feb 18 18:05:17 2016 @@ -2319,12 +2319,44 @@ CommandInterpreter::SourceInitFile (bool FileSpec init_file; if (in_cwd) { - // In the current working directory we don't load any program specific - // .lldbinit files, we only look for a "./.lldbinit" file. - if (m_skip_lldbinit_files) - return; + ExecutionContext exe_ctx(GetExecutionContext()); + Target *target = exe_ctx.GetTargetPtr(); + if (target) + { + // In the current working directory we don't load any program specific + // .lldbinit files, we only look for a ".lldbinit" file. + if (m_skip_lldbinit_files) + return; - init_file.SetFile ("./.lldbinit", true); + LoadCWDlldbinitFile should_load = target->TargetProperties::GetLoadCWDlldbinitFile (); + if (should_load == eLoadCWDlldbinitWarn) + { + FileSpec dot_lldb (".lldbinit", true); + llvm::SmallString<64> home_dir_path; + llvm::sys::path::home_directory (home_dir_path); + FileSpec homedir_dot_lldb (home_dir_path.c_str(), false); + homedir_dot_lldb.AppendPathComponent (".lldbinit"); + homedir_dot_lldb.ResolvePath (); + if (dot_lldb.Exists () + && dot_lldb.GetDirectory() != homedir_dot_lldb.GetDirectory()) + { + result.AppendErrorWithFormat ( + "There is a .lldbinit file in the current directory which is not being read.\n" + "To silence this warning without sourcing in the local .lldbinit,\n" + "add the following to the lldbinit file in your home directory:\n" + " settings set target.load-cwd-lldbinit false\n" + "To allow lldb to source .lldbinit files in the current working directory,\n" + "set the value of this variable to true. Only do so if you understand and\n" + "accept the security risk."); + result.SetStatus (eReturnStatusFailed); + return; + } + } + else if (should_load == eLoadCWDlldbinitTrue) + { + init_file.SetFile ("./.lldbinit", true); + } + } } else { Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Thu Feb 18 18:05:17 2016 @@ -3363,6 +3363,15 @@ g_load_script_from_sym_file_values[] = }; static OptionEnumValueElement +g_load_current_working_dir_lldbinit_values[] = +{ + { eLoadCWDlldbinitTrue, "true", "Load .lldbinit files from current directory"}, + { eLoadCWDlldbinitFalse, "false", "Do not load .lldbinit files from current directory"}, + { eLoadCWDlldbinitWarn, "warn", "Warn about loading .lldbinit files from current directory"}, + { 0, nullptr, nullptr } +}; + +static OptionEnumValueElement g_memory_module_load_level_values[] = { { eMemoryModuleLoadLevelMinimal, "minimal" , "Load minimal information when loading modules from memory. Currently this setting loads sections only."}, @@ -3418,6 +3427,7 @@ g_properties[] = { "hex-immediate-style" , OptionValue::eTypeEnum , false, Disassembler::eHexStyleC, nullptr, g_hex_immediate_style_values, "Which style to use for printing hexadecimal disassembly values." }, { "use-fast-stepping" , OptionValue::eTypeBoolean , false, true, nullptr, nullptr, "Use a fast stepping algorithm based on running from branch to branch rather than instruction single-stepping." }, { "load-script-from-symbol-file" , OptionValue::eTypeEnum , false, eLoadScriptFromSymFileWarn, nullptr, g_load_script_from_sym_file_values, "Allow LLDB to load scripting resources embedded in symbol files when available." }, + { "load-cwd-lldbinit" , OptionValue::eTypeEnum , false, eLoadCWDlldbinitWarn, nullptr, g_load_current_working_dir_lldbinit_values, "Allow LLDB to .lldbinit files from the current directory automatically." }, { "memory-module-load-level" , OptionValue::eTypeEnum , false, eMemoryModuleLoadLevelComplete, nullptr, g_memory_module_load_level_values, "Loading modules from memory can be slow as reading the symbol tables and other data can take a long time depending on your connection to the debug target. " "This setting helps users control how much information gets loaded when loading modules from memory." @@ -3465,6 +3475,7 @@ enum ePropertyHexImmediateStyle, ePropertyUseFastStepping, ePropertyLoadScriptFromSymbolFile, + ePropertyLoadCWDlldbinitFile, ePropertyMemoryModuleLoadLevel, ePropertyDisplayExpressionsInCrashlogs, ePropertyTrapHandlerNames, @@ -3945,6 +3956,13 @@ TargetProperties::GetLoadScriptFromSymbo return (LoadScriptFromSymFile)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value); } +LoadCWDlldbinitFile +TargetProperties::GetLoadCWDlldbinitFile () const +{ + const uint32_t idx = ePropertyLoadCWDlldbinitFile; + return (LoadCWDlldbinitFile) m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value); +} + Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle () const { Modified: lldb/trunk/tools/driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.cpp (original) +++ lldb/trunk/tools/driver/Driver.cpp Thu Feb 18 18:05:17 2016 @@ -38,6 +38,7 @@ #include "lldb/API/SBLanguageRuntime.h" #include "lldb/API/SBListener.h" #include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" #include "lldb/API/SBTarget.h" #include "lldb/API/SBThread.h" #include "lldb/API/SBProcess.h" @@ -441,13 +442,24 @@ Driver::OptionData::Clear () m_script_lang = lldb::eScriptLanguageDefault; m_initial_commands.clear (); m_after_file_commands.clear (); - // If there is a local .lldbinit, source that: - SBFileSpec local_lldbinit("./.lldbinit", true); - if (local_lldbinit.Exists()) + + // If there is a local .lldbinit, add that to the + // list of things to be sourced, if the settings + // permit it. + SBFileSpec local_lldbinit (".lldbinit", true); + + SBFileSpec homedir_dot_lldb = SBHostOS::GetUserHomeDirectory(); + homedir_dot_lldb.AppendPathComponent (".lldbinit"); + + // Only read .lldbinit in the current working directory + // if it's not the same as the .lldbinit in the home + // directory (which is already being read in). + if (local_lldbinit.Exists() + && strcmp (local_lldbinit.GetDirectory(), homedir_dot_lldb.GetDirectory()) != 0) { char path[2048]; local_lldbinit.GetPath(path, 2047); - InitialCmdEntry entry(path, true, true); + InitialCmdEntry entry(path, true, true, true); m_after_file_commands.push_back (entry); } @@ -486,18 +498,18 @@ Driver::OptionData::AddInitialCommand (c { SBFileSpec file(command); if (file.Exists()) - command_set->push_back (InitialCmdEntry(command, is_file)); + command_set->push_back (InitialCmdEntry(command, is_file, false)); else if (file.ResolveExecutableLocation()) { char final_path[PATH_MAX]; file.GetPath (final_path, sizeof(final_path)); - command_set->push_back (InitialCmdEntry(final_path, is_file)); + command_set->push_back (InitialCmdEntry(final_path, is_file, false)); } else error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg); } else - command_set->push_back (InitialCmdEntry(command, is_file)); + command_set->push_back (InitialCmdEntry(command, is_file, false)); } void @@ -550,6 +562,30 @@ Driver::WriteCommandsForSourcing (Comman const char *command = command_entry.contents.c_str(); if (command_entry.is_file) { + // If this command_entry is a file to be sourced, and it's the ./.lldbinit file (the .lldbinit + // file in the current working directory), only read it if target.load-cwd-lldbinit is 'true'. + if (command_entry.is_cwd_lldbinit_file_read) + { + SBStringList strlist = m_debugger.GetInternalVariableValue ("target.load-cwd-lldbinit", + m_debugger.GetInstanceName()); + if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "warn") == 0) + { + FILE *output = m_debugger.GetOutputFileHandle (); + ::fprintf (output, + "There is a .lldbinit file in the current directory which is not being read.\n" + "To silence this warning without sourcing in the local .lldbinit,\n" + "add the following to the lldbinit file in your home directory:\n" + " settings set target.load-cwd-lldbinit false\n" + "To allow lldb to source .lldbinit files in the current working directory,\n" + "set the value of this variable to true. Only do so if you understand and\n" + "accept the security risk.\n"); + return; + } + if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "false") == 0) + { + return; + } + } bool source_quietly = m_option_data.m_source_quietly || command_entry.source_quietly; strm.Printf("command source -s %i '%s'\n", source_quietly, command); } @@ -1033,7 +1069,7 @@ Driver::MainLoop () SBStream commands_stream; // First source in the commands specified to be run before the file arguments are processed. - WriteCommandsForSourcing(eCommandPlacementBeforeFile, commands_stream); + WriteCommandsForSourcing (eCommandPlacementBeforeFile, commands_stream); const size_t num_args = m_option_data.m_args.size(); if (num_args > 0) Modified: lldb/trunk/tools/driver/Driver.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.h?rev=261280&r1=261279&r2=261280&view=diff ============================================================================== --- lldb/trunk/tools/driver/Driver.h (original) +++ lldb/trunk/tools/driver/Driver.h Thu Feb 18 18:05:17 2016 @@ -81,14 +81,16 @@ public: struct InitialCmdEntry { - InitialCmdEntry (const char *in_contents, bool in_is_file, bool in_quiet = false) : + InitialCmdEntry (const char *in_contents, bool in_is_file, bool is_cwd_lldbinit_file_read, bool in_quiet = false) : contents (in_contents), is_file (in_is_file), - source_quietly(in_quiet) + is_cwd_lldbinit_file_read (is_cwd_lldbinit_file_read), + source_quietly (in_quiet) {} std::string contents; bool is_file; + bool is_cwd_lldbinit_file_read; // if this is reading ./.lldbinit - so we may skip if not permitted bool source_quietly; }; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits