From bacd2e8c27d203880a9066e2c214fb0a15344078 Mon Sep 17 00:00:00 2001 From: adfoster-r7 Date: Thu, 14 Sep 2023 12:53:05 +0100 Subject: [PATCH] Add thread killing logic --- foo.rb | 22 +++++++++++++++++++ .../framework/spec/threads/suite.rb | 5 +++-- lib/msf/core/thread_manager.rb | 2 +- lib/msf/ui/web/web_console.rb | 4 ++++ lib/rex/ui/text/shell.rb | 5 +++++ .../contexts/msf/framework/threads/cleaner.rb | 1 + 6 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 foo.rb diff --git a/foo.rb b/foo.rb new file mode 100644 index 0000000000000..41c7448e4f073 --- /dev/null +++ b/foo.rb @@ -0,0 +1,22 @@ +t = Thread.new do + loop do + begin + sleep 1 + rescue ::Exception + $stderr.puts "not today!" + ensure + $stderr.puts 'ensure still runs' + raise 'meow' + sleep 20 + $stderr.puts "sleeping" + end + end +end + +sleep 1 + +puts "kill" +t.kill +puts "joining" +t.join +puts "joined" diff --git a/lib/metasploit/framework/spec/threads/suite.rb b/lib/metasploit/framework/spec/threads/suite.rb index b225c3c9263b1..f97b0fee30a00 100644 --- a/lib/metasploit/framework/spec/threads/suite.rb +++ b/lib/metasploit/framework/spec/threads/suite.rb @@ -96,6 +96,7 @@ def self.configure! thread_list.each do |thread| thread_uuid = thread[Metasploit::Framework::Spec::Threads::Suite::UUID_THREAD_LOCAL_VARIABLE] + thread_name = thread[:tm_name] # unmanaged thread, such as the main VM thread unless thread_uuid @@ -104,10 +105,10 @@ def self.configure! caller = caller_by_thread_uuid[thread_uuid] - error_lines << "Thread #{thread_uuid}'s status is #{thread.status.inspect} " \ + error_lines << "Thread #{thread_uuid}'s (name=#{thread_name} status is #{thread.status.inspect} " \ "and was started here:\n" - error_lines.concat(caller) + error_lines << "The thread backtrace was:\n#{thread.backtrace ? thread.backtrace.join("\n") : 'nil (no backtrace)'}\n" end else error_lines << "Run `rake spec` to log where Thread.new is called." diff --git a/lib/msf/core/thread_manager.rb b/lib/msf/core/thread_manager.rb index 7fe59f501805e..de512cdbec613 100644 --- a/lib/msf/core/thread_manager.rb +++ b/lib/msf/core/thread_manager.rb @@ -59,7 +59,7 @@ def initialize(framework) # XXX: Preserve Ruby < 2.5 thread exception reporting behavior # https://ruby-doc.org/core-2.5.0/Thread.html#method-c-report_on_exception if Thread.method_defined?(:report_on_exception=) - Thread.report_on_exception = false + Thread.report_on_exception = true end end diff --git a/lib/msf/ui/web/web_console.rb b/lib/msf/ui/web/web_console.rb index 042f162465645..142346139b199 100644 --- a/lib/msf/ui/web/web_console.rb +++ b/lib/msf/ui/web/web_console.rb @@ -116,8 +116,12 @@ def tab_complete(cmd) end def shutdown + $stderr.puts 'shutting down webconsole' + require 'pry-byebug'; binding.pry self.pipe.close + $stderr.puts 'closed pipe' self.thread.kill + $stderr.puts "thread killed #{self.thread}" end def busy diff --git a/lib/rex/ui/text/shell.rb b/lib/rex/ui/text/shell.rb index 0e1e1459d569a..96a08fabcc1d3 100644 --- a/lib/rex/ui/text/shell.rb +++ b/lib/rex/ui/text/shell.rb @@ -172,13 +172,18 @@ def run(&block) end # Prevent accidental console quits rescue ::Interrupt + $stderr.puts "Was interrupted, doing a retry!" output.print("Interrupt: use the 'exit' command to quit\n") retry end end ensure + $stderr.puts "Ensure cleanup for shell" + $stderr.puts "Flushing history manager" HistoryManager.instance.flush + $stderr.puts "History managed flushed" self.hist_last_saved = Readline::HISTORY.length + $stderr.puts "Finished restoring history" end # diff --git a/spec/support/shared/contexts/msf/framework/threads/cleaner.rb b/spec/support/shared/contexts/msf/framework/threads/cleaner.rb index b2c6c62acf2a1..2b0ea95159ff1 100644 --- a/spec/support/shared/contexts/msf/framework/threads/cleaner.rb +++ b/spec/support/shared/contexts/msf/framework/threads/cleaner.rb @@ -16,6 +16,7 @@ thread_manager.each do |thread| puts "-----------------------------------------------------" thread_deets = "thread=#{thread} - name=#{thread[:tm_name]} --- backtrace=#{thread.backtrace ? thread.backtrace.join("\n") : 'no backtrace'} ---" + $stderr.puts "killing thread #{thread_deets}" thread.kill $stderr.puts "Waiting to join"