[Lldb-commits] [lldb] r261280 - This patch stops lldb from loading a .lldbinit file from the current

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Thu Feb 18 16:05:18 PST 2016


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;
         };
 




More information about the lldb-commits mailing list