dce2_smb_stats.total_smb2_sessions++;
}
-Dce2Smb2SessionData::~Dce2Smb2SessionData()
+Dce2Smb2SessionData::~Dce2Smb2SessionData(void)
{
session_data_mutex.lock();
for (auto it_session : connected_sessions)
{
it_session.second->detach_flow(flow_key);
}
+
+ if (get_tcp_file_tracker() && !(get_tcp_file_tracker()->get_flow_state_map().empty()))
+ {
+ get_tcp_file_tracker()->get_flow_state_map().erase(flow_key);
+ tcp_file_tracker = nullptr;
+ }
session_data_mutex.unlock();
}
void Dce2Smb2SessionData::reset_matching_tcp_file_tracker(
- Dce2Smb2FileTracker* file_tracker)
+ Dce2Smb2FileTrackerPtr file_tracker)
{
std::lock_guard<std::mutex> guard(tcp_file_tracker_mutex);
if (tcp_file_tracker == file_tracker)
- tcp_file_tracker = nullptr;
+ {
+ if (get_tcp_file_tracker() && !(get_tcp_file_tracker()->get_flow_state_map().empty()))
+ {
+ get_tcp_file_tracker()->get_flow_state_map().erase(flow_key);
+ tcp_file_tracker = nullptr;
+ }
+ else
+ return;
+ }
}
Smb2SessionKey Dce2Smb2SessionData::get_session_key(uint64_t session_id)
uint16_t structure_size = alignedNtohs((const uint16_t*)smb_data);
uint16_t command = alignedNtohs(&(smb_hdr->command));
uint64_t session_id = Smb2Sid(smb_hdr);
- Dce2Smb2SessionTrackerPtr session = find_session(session_id);
+ Dce2Smb2SessionTrackerPtr session;
// Macro and shorthand to save some repetitive code
// Should only be used in this function
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL \
, GET_CURRENT_PACKET, "%s: invalid struct size\n", \
smb2_command_string[command]); \
- if (session) \
+ if (session) \
{ \
session->set_do_not_delete(false); \
session->set_prev_comand(SMB2_COM_MAX); \
flow_key, Smb2Mid(smb_hdr), session_id, Smb2Tid(smb_hdr));
// Handling case of two threads trying to do close same session at a time
- if (command == SMB2_COM_CLOSE and (session and session->get_prev_command() != SMB2_COM_MAX))
+ session = find_session(session_id);
+ if ((command == SMB2_COM_CLOSE or command ==
+ SMB2_COM_TREE_DISCONNECT) and (session and session->get_prev_command() != SMB2_COM_MAX))
{
- session->set_do_not_delete(false);
return;
}
{
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL,
p, "Encrypted header is received \n");
- Dce2Smb2SessionTrackerPtr session = find_session(sid);
+ session = find_session(sid);
if (session)
{
bool flag = session->get_encryption_flag();
{
if ( tcp_file_tracker )
{
- session = find_session(tcp_file_tracker->get_session_id());
- if (session)
- session->set_do_not_delete(true);
+ session = find_session (tcp_file_tracker->get_session_id());
+ if (session)
+ session->set_do_not_delete(true);
}
+ else
+ return;
tcp_file_tracker_mutex.lock();
- if ( tcp_file_tracker and tcp_file_tracker->accepting_raw_data_from(flow_key))
+ if ( tcp_file_tracker and tcp_file_tracker.use_count() >
+ 1 and tcp_file_tracker->accepting_raw_data_from(flow_key))
{
SMB_DEBUG(dce_smb_trace,DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p, "processing raw data for file id %" PRIu64 "\n",
tcp_file_tracker->get_file_id());
- tcp_file_tracker->process_data(flow_key, data_ptr, data_len);
+ tcp_file_tracker->process_data(flow_key, data_ptr, data_len, session);
tcp_file_tracker->stop_accepting_raw_data_from(flow_key);
}
+ else if (tcp_file_tracker and tcp_file_tracker.use_count() == 1)
+ {
+ if (get_tcp_file_tracker() && !(get_tcp_file_tracker()->get_flow_state_map().empty()))
+ {
+ get_tcp_file_tracker()->get_flow_state_map().erase(flow_key);
+ tcp_file_tracker = nullptr;
+ }
+ }
else
{
SMB_DEBUG(dce_smb_trace,DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p, "not processing raw data\n");
using Dce2Smb2SessionTrackerMap =
std::unordered_map<uint64_t, Dce2Smb2SessionTrackerPtr, std::hash<uint64_t> >;
+using Dce2Smb2FileTrackerPtr = std::shared_ptr<Dce2Smb2FileTracker>;
+using Dce2Smb2FileTrackerMap =
+ std::unordered_map<uint64_t, Dce2Smb2FileTrackerPtr, std::hash<uint64_t> >;
+
PADDING_GUARD_BEGIN
struct Smb2SessionKey
{
void process() override;
void remove_session(uint64_t, bool = false);
void handle_retransmit(FilePosition, FileVerdict) override { }
- void reset_matching_tcp_file_tracker(Dce2Smb2FileTracker*);
+ void reset_matching_tcp_file_tracker(Dce2Smb2FileTrackerPtr);
void set_reassembled_data(uint8_t*, uint16_t) override;
uint32_t get_flow_key() { return flow_key; }
- void set_tcp_file_tracker(Dce2Smb2FileTracker* file_tracker)
+ void set_tcp_file_tracker(Dce2Smb2FileTrackerPtr file_tracker)
{
std::lock_guard<std::mutex> guard(session_data_mutex);
tcp_file_tracker = file_tracker;
}
+ Dce2Smb2FileTrackerPtr get_tcp_file_tracker()
+ {
+ return tcp_file_tracker;
+ }
+
+ Dce2Smb2SessionTrackerPtr find_session(uint64_t);
+
private:
void process_command(const Smb2Hdr*, const uint8_t*);
Smb2SessionKey get_session_key(uint64_t);
Dce2Smb2SessionTrackerPtr create_session(uint64_t);
- Dce2Smb2SessionTrackerPtr find_session(uint64_t);
+ Dce2Smb2FileTrackerPtr tcp_file_tracker;
uint32_t flow_key;
- Dce2Smb2FileTracker* tcp_file_tracker;
Dce2Smb2SessionTrackerMap connected_sessions;
std::mutex session_data_mutex;
std::mutex tcp_file_tracker_mutex;
#include "hash/hash_key_operations.h"
#include "dce_co.h"
+#include "dce_smb2.h"
#include "dce_smb2_session.h"
#include "dce_smb2_tree.h"
+#include <mutex>
using namespace snort;
#define UNKNOWN_FILE_SIZE (~0)
-void Dce2Smb2FileTracker::accept_raw_data_from(Dce2Smb2SessionData* flow, uint64_t offset)
+void Dce2Smb2FileTracker::accept_raw_data_from(Dce2Smb2SessionData* flow, uint64_t offset, Dce2Smb2FileTrackerPtr file_tracker)
{
if (flow)
{
}
current_flow_state.pdu_state = DCE2_SMB_PDU_STATE__RAW_DATA;
- flow->set_tcp_file_tracker(this);
+ flow->set_tcp_file_tracker(file_tracker);
}
}
void Dce2Smb2FileTracker::stop_accepting_raw_data_from(uint32_t current_flow_key)
}
std::pair<bool, Dce2Smb2SessionData*> Dce2Smb2FileTracker::update_processing_flow(
- Dce2Smb2SessionData* current_flow)
+ Dce2Smb2SessionData* current_flow,Dce2Smb2SessionTrackerPtr session_tracker)
{
std::lock_guard<std::mutex> guard(process_file_mutex);
bool switched = false;
- Dce2Smb2SessionData* processing_flow = parent_tree->get_parent()->get_flow(file_flow_key);
+ Dce2Smb2SessionData* processing_flow;
+ if (session_tracker)
+ processing_flow = session_tracker->get_flow(file_flow_key);
+ else
+ processing_flow = parent_tree->get_parent()->get_flow(file_flow_key);
+
if (!processing_flow)
{
switched = true;
FileContext* file = get_smb_file_context(flow, file_name_hash, file_id, false);
if (file)
file->set_file_size(file_size);
- return (!process_data(current_flow_key, nullptr, 0));
+
+ Dce2Smb2SessionTrackerPtr ses_ptr = processing_flow->find_session(session_id);
+ return (!process_data(current_flow_key, nullptr, 0,ses_ptr));
}
return true;
}
current_flow_state.file_offset = offset;
current_flow_state.max_offset = offset + max_offset;
flow_state_mutex.unlock();
- return process_data(current_flow_key, file_data, data_size);
-}
-
-bool Dce2Smb2FileTracker::process_data(const uint32_t current_flow_key, const uint8_t* file_data,
- uint32_t data_size)
-{
- Dce2Smb2SessionData* current_flow = parent_tree->get_parent()->get_flow(current_flow_key);
- if (!current_flow)
- return true;
-
+ Dce2Smb2SessionTracker *sess = parent_tree->get_parent();
if (parent_tree->get_share_type() != SMB2_SHARE_TYPE_DISK)
{
+ Dce2Smb2SessionData *current_flow = nullptr;
+ if (sess)
+ {
+ parent_tree->get_parent()->set_do_not_delete(true);
+ current_flow = parent_tree->get_parent()->get_flow(current_flow_key);
+ if (!current_flow)
+ {
+ parent_tree->get_parent()->set_do_not_delete(false);
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
if (data_size > UINT16_MAX)
{
data_size = UINT16_MAX;
}
- DCE2_CoProcess(current_flow->get_dce2_session_data(), parent_tree->get_cotracker(),
- file_data, data_size);
+ if (parent_tree->get_cotracker())
+ {
+ sess->co_tracker_mutex.lock();
+ DCE2_CoProcess(current_flow->get_dce2_session_data(), parent_tree->get_cotracker(),
+ file_data, data_size);
+ sess->co_tracker_mutex.unlock();
+ }
+ parent_tree->get_parent()->set_do_not_delete(false);
return true;
}
+ Dce2Smb2SessionData *current_flow = sess->get_flow(current_flow_key);
+ Dce2Smb2SessionTrackerPtr ses_ptr = current_flow->find_session(session_id);
+ return process_data(current_flow_key, file_data, data_size,ses_ptr);
+}
+
+bool Dce2Smb2FileTracker::process_data(const uint32_t current_flow_key, const uint8_t* file_data,
+ uint32_t data_size,Dce2Smb2SessionTrackerPtr session_tracker)
+{
+ Dce2Smb2SessionData *current_flow;
+ if (session_tracker)
+ {
+ session_tracker->set_do_not_delete(true);
+ current_flow = session_tracker->get_flow(current_flow_key);
+ }
+ else
+ return false;
+
+ if (!current_flow)
+ {
+ session_tracker->set_do_not_delete(false);
+ return true;
+ }
int64_t file_detection_depth = current_flow->get_smb_file_depth();
int64_t detection_size = 0;
{
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, p,
"file name not set , ignored\n");
+ session_tracker->set_do_not_delete(false);
return true;
}
&dce2_smb_stats, *(current_flow->get_dce2_session_data()));
}
- auto updated_flow = update_processing_flow(current_flow);
+ auto updated_flow = update_processing_flow(current_flow, session_tracker);
Dce2Smb2SessionData* processing_flow = updated_flow.second;
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p,"file_process fid %" PRIu64 " data_size %"
if (!file_flows)
{
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_CRITICAL_LEVEL, p, "file_flows not found\n");
+ session_tracker->set_do_not_delete(false);
return true;
}
if (!continue_processing)
{
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p, "file_process completed\n");
+ session_tracker->set_do_not_delete(false);
return false;
}
flow_state_mutex.lock();
flow_state[current_flow_key].file_offset = file_offset;
flow_state_mutex.unlock();
+ session_tracker->set_do_not_delete(false);
return true;
}
-Dce2Smb2FileTracker::~Dce2Smb2FileTracker()
+Dce2Smb2FileTracker::~Dce2Smb2FileTracker(void)
{
- if (smb_module_is_up and (is_packet_thread()))
- {
- SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET, "file tracker %" PRIu64
- " file name hash %" PRIu64 " terminating\n", file_id, file_name_hash);
- }
-
if (file_name)
snort_free((void*)file_name);
- parent_tree->get_parent()->clean_file_context_from_flow(this, file_id, file_name_hash);
+ file_name = nullptr;
+ parent_tree = nullptr;
}
// This provides file tracker for SMBv2
#include "dce_smb2.h"
+#include <atomic>
class Dce2Smb2TreeTracker;
~Dce2Smb2FileTracker();
bool process_data(const uint32_t, const uint8_t*, uint32_t, const uint64_t, uint64_t);
- bool process_data(const uint32_t, const uint8_t*, uint32_t);
+ bool process_data(const uint32_t, const uint8_t*, uint32_t, Dce2Smb2SessionTrackerPtr);
bool close(const uint32_t);
void set_info(char*, uint16_t, uint64_t);
- void accept_raw_data_from(Dce2Smb2SessionData*, uint64_t = 0);
+ void accept_raw_data_from(Dce2Smb2SessionData*, uint64_t, Dce2Smb2FileTrackerPtr);
bool accepting_raw_data_from(uint32_t current_flow_key)
{
std::lock_guard<std::mutex> guard(flow_state_mutex);
void set_direction(FileDirection dir) { direction = dir; }
Dce2Smb2TreeTracker* get_parent() { return parent_tree; }
+ void set_parent(Dce2Smb2TreeTracker* pt) { parent_tree = pt; }
uint64_t get_file_id() { return file_id; }
+ uint64_t get_file_name_hash() { return file_name_hash; }
uint64_t get_session_id() { return session_id; }
+ std::unordered_map<uint32_t, tcp_flow_state, std::hash<uint32_t> > get_flow_state_map()
+ {
+ return flow_state;
+ }
private:
void file_detect();
- std::pair<bool, Dce2Smb2SessionData*> update_processing_flow(Dce2Smb2SessionData* = nullptr);
+ std::pair<bool, Dce2Smb2SessionData*> update_processing_flow(Dce2Smb2SessionData* = nullptr,
+ Dce2Smb2SessionTrackerPtr session_tracker = nullptr);
bool ignore;
uint16_t file_name_len;
uint32_t file_flow_key;
std::mutex flow_state_mutex;
};
-using Dce2Smb2FileTrackerMap =
- std::unordered_map<uint64_t, Dce2Smb2FileTracker*, std::hash<uint64_t> >;
+using Dce2Smb2FileTrackerPtr = std::shared_ptr<Dce2Smb2FileTracker>;
+using Dce2Smb2FileTrackerMap =
+ std::unordered_map<uint64_t, Dce2Smb2FileTrackerPtr, std::hash<uint64_t> >;
#endif
~Dce2Smb2RequestTracker()
{
- if (smb_module_is_up and (snort::is_packet_thread()))
- {
- SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET, "request tracker terminating\n");
- }
if (fname)
snort_free(fname);
}
}
break;
case SMB2_COM_TREE_DISCONNECT:
- if (tree)
- {
- delete tree;
- connected_trees_mutex.lock();
- connected_trees.erase(tree_id);
- connected_trees_mutex.unlock();
- }
- else
- dce2_smb_stats.v2_tree_discn_ignored++;
- break;
+ {
+ if (!tree)
+ dce2_smb_stats.v2_tree_discn_ignored++;
+ }
+ break;
//for all other cases, tree tracker should handle the command
case SMB2_COM_CREATE:
return tree;
}
-void Dce2Smb2SessionTracker::clean_file_context_from_flow(Dce2Smb2FileTracker* file_tracker,
- uint64_t file_id, uint64_t file_name_hash)
+void Dce2Smb2SessionTracker::clean_file_context_from_flow(uint64_t file_id, uint64_t
+ file_name_hash)
{
+ set_do_not_delete(true);
attached_flows_mutex.lock();
for (auto it_flow : attached_flows)
{
it_flow.second->get_tcp_flow(), false);
if (file_flows)
file_flows->remove_processed_file_context(file_name_hash, file_id);
- it_flow.second->reset_matching_tcp_file_tracker(file_tracker);
}
attached_flows_mutex.unlock();
+ set_do_not_delete(false);
}
void Dce2Smb2SessionTracker::increase_size(const size_t size)
}
// Session Tracker is created and destroyed only from session cache
-Dce2Smb2SessionTracker::~Dce2Smb2SessionTracker()
+Dce2Smb2SessionTracker::~Dce2Smb2SessionTracker(void)
{
if (!(fcfs_mutex.try_lock()))
return;
fcfs_mutex.unlock();
return;
}
- if (smb_module_is_up and (snort::is_packet_thread()))
- {
- SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID,
- TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET,
- "session tracker %" PRIu64 " terminating\n", session_id);
- }
std::vector<Dce2Smb2TreeTracker*> all_trees;
connected_trees_mutex.lock();
}
Smb2SessionKey get_key() { return session_key; }
- void clean_file_context_from_flow(Dce2Smb2FileTracker*, uint64_t, uint64_t);
+ void clean_file_context_from_flow(uint64_t, uint64_t);
void unlink();
Dce2Smb2SessionData* get_flow(uint32_t);
void process(const uint16_t, uint8_t, const Smb2Hdr*, const uint8_t*, const uint32_t);
bool get_do_not_delete() { return do_not_delete; }
void set_prev_comand(uint16_t cmd) { command_prev = cmd; }
uint16_t get_prev_command() { return command_prev; }
+ std::mutex co_tracker_mutex;
void set_encryption_flag(bool flag)
{
encryption_flag = flag;
data.emplace_back(list_iter->second); // increase reference count
// This instructs the session_tracker to take a lock before detaching
// from ssd, when it is getting destroyed.
- list_iter->second->set_reload_prune(true);
- decrease_size(list_iter->second.get());
- map.erase(list_iter->first);
- list.erase(list_iter);
- ++stats.reload_prunes;
+ if (!list_iter->second->get_do_not_delete())
+ {
+ list_iter->second->set_reload_prune(true);
+ decrease_size(list_iter->second.get());
+ map.erase(list_iter->first);
+ list.erase(list_iter);
+ ++stats.reload_prunes;
+ }
+ else
+ {
+ // Move entry to front of LruList
+ list.splice(list.begin(), list, list_iter);
+ }
}
}
#include "dce_smb2_tree.h"
#include "dce_smb2_session.h"
+#include <memory>
using namespace snort;
return alignedNtohq(&(hdr->message_id));
}
-Dce2Smb2FileTracker* Dce2Smb2TreeTracker::open_file(const uint64_t file_id,
+Dce2Smb2FileTrackerPtr Dce2Smb2TreeTracker::open_file(const uint64_t file_id,
const uint32_t current_flow_key)
{
- Dce2Smb2FileTracker* ftracker = new Dce2Smb2FileTracker(file_id, current_flow_key, this,
- this->get_parent()->get_session_id());
+ std::shared_ptr<Dce2Smb2FileTracker> ftracker = std::make_shared<Dce2Smb2FileTracker> (
+ file_id, current_flow_key, this, this->get_parent()->get_session_id());
tree_tracker_mutex.lock();
opened_files.insert(std::make_pair(file_id, ftracker));
tree_tracker_mutex.unlock();
return ftracker;
}
-Dce2Smb2FileTracker* Dce2Smb2TreeTracker::find_file(uint64_t file_id)
+Dce2Smb2FileTrackerPtr Dce2Smb2TreeTracker::find_file(uint64_t file_id)
{
std::lock_guard<std::mutex> guard(tree_tracker_mutex);
auto it_file = opened_files.find(file_id);
auto it_file = opened_files.find(file_id);
if (it_file != opened_files.end())
{
- Dce2Smb2FileTracker* file = it_file->second;
+ Dce2Smb2FileTrackerPtr file = it_file->second;
+ it_file->second->set_parent(nullptr);
if (opened_files.erase(file_id) and destroy)
{
parent_session->decrease_size(sizeof(Dce2Smb2FileTracker));
tree_tracker_mutex.unlock();
- delete file;
return;
}
}
uint64_t file_size = alignedNtohq((const uint64_t*)((const uint8_t*)
set_info_hdr + SMB2_SET_INFO_REQUEST_STRUC_SIZE - 1));
uint64_t file_id = alignedNtohq(&(set_info_hdr->fileId_persistent));
- Dce2Smb2FileTracker* file_tracker = find_file(file_id);
+
+ do_not_delete_tree = true;
+ Dce2Smb2FileTrackerPtr file_tracker = find_file(file_id);
if (file_tracker)
file_tracker->set_info(nullptr, 0, file_size);
else
GET_CURRENT_PACKET, "%s_REQ: ftracker missing\n",
smb2_command_string[SMB2_COM_SET_INFO]);
}
+ do_not_delete_tree = false;
}
else
{
const uint8_t* smb_data = (const uint8_t*)smb_header + SMB2_HEADER_LENGTH;
uint64_t file_id = alignedNtohq(&(((const Smb2CloseRequestHdr*)
smb_data)->fileId_persistent));
- Dce2Smb2FileTracker* file_tracker = find_file(file_id);
+
+ do_not_delete_tree = true;
+ Dce2Smb2FileTrackerPtr file_tracker = find_file(file_id);
if (!file_tracker)
{
dce2_smb_stats.v2_cls_req_ftrkr_misng++;
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL,
GET_CURRENT_PACKET, "%s_REQ: ftracker missing %" PRIu64 "\n",
smb2_command_string[SMB2_COM_CLOSE], file_id);
+ do_not_delete_tree = false;
return;
}
if (file_tracker->close(current_flow_key))
- close_file(file_id);
+ close_file(file_id, true);
+
+ do_not_delete_tree = false;
if (share_type != SMB2_SHARE_TYPE_DISK)
- DCE2_CoCleanTracker(co_tracker);
+ {
+ if (co_tracker != nullptr)
+ {
+ DCE2_CoCleanTracker(co_tracker);
+ snort_free((void*)co_tracker);
+ co_tracker = nullptr;
+ }
+ }
}
uint64_t Dce2Smb2TreeTracker::get_durable_file_id(
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL,
GET_CURRENT_PACKET, "%s_RESP: not processing for directory\n",
smb2_command_string[SMB2_COM_CREATE]);
- close_file(file_id);
+ close_file(file_id, true);
}
else
{
+ do_not_delete_tree = true;
Dce2Smb2RequestTracker* create_request = find_request(message_id, current_flow_key);
if (create_request)
{
- Dce2Smb2FileTracker* file_tracker = find_file(file_id);
+ Dce2Smb2FileTrackerPtr file_tracker = find_file(file_id);
if (!file_tracker)
file_tracker = open_file(file_id, current_flow_key);
smb2_command_string[SMB2_COM_CREATE]);
dce2_smb_stats.v2_crt_rtrkr_misng++;
}
+ do_not_delete_tree = false;
}
}
{
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL,
GET_CURRENT_PACKET, "requested file_id %lu\n", file_id);
- Dce2Smb2FileTracker* file_tracker = find_file(file_id);
+ do_not_delete_tree = true;
+ Dce2Smb2FileTrackerPtr file_tracker = find_file(file_id);
if (!file_tracker)
{
file_tracker = open_file(file_id, current_flow_key);
file_tracker->set_info(file_name, name_len, 0);
}
}
+ do_not_delete_tree = false;
}
}
const uint8_t* smb_data = (const uint8_t*)smb_header + SMB2_HEADER_LENGTH;
const Smb2ReadResponseHdr* read_resp_hdr = (const Smb2ReadResponseHdr*)smb_data;
- Dce2Smb2RequestTracker* read_request = find_request(message_id, current_flow_key);
- if (!read_request)
- {
- SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL,
- GET_CURRENT_PACKET, "SMB2_COM_READ_RESP: request tracker missing\n");
- dce2_smb_stats.v2_read_rtrkr_misng++;
- return;
- }
-
uint16_t data_offset = alignedNtohs((const uint16_t*)(&(read_resp_hdr->data_offset)));
Dce2Smb2SessionData* current_flow = parent_session->get_flow(current_flow_key);
if (data_offset + (const uint8_t*)smb_header > end)
dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats,
*current_flow->get_dce2_session_data());
}
- Dce2Smb2FileTracker* file_tracker = find_file(read_request->get_file_id());
+
+ do_not_delete_tree = true;
+
+ Dce2Smb2RequestTracker* read_request = find_request(message_id, current_flow_key);
+ if (!read_request)
+ {
+ SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL,
+ GET_CURRENT_PACKET, "SMB2_COM_READ_RESP: request tracker missing\n");
+ dce2_smb_stats.v2_read_rtrkr_misng++;
+ do_not_delete_tree = false;
+ return;
+ }
+
+ Dce2Smb2FileTrackerPtr file_tracker = find_file(read_request->get_file_id());
if (file_tracker)
{
const uint8_t* file_data = (const uint8_t*)read_resp_hdr +
{
if ((uint32_t)data_size < alignedNtohl((const uint32_t*)&(read_resp_hdr->length)))
{
- file_tracker->accept_raw_data_from(current_flow);
+ file_tracker->accept_raw_data_from(current_flow, 0, file_tracker);
}
}
}
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL,
GET_CURRENT_PACKET, "SMB2_COM_READ_RESP: file tracker missing\n");
}
+ do_not_delete_tree = false;
}
void Dce2Smb2TreeTracker::process_read_request(const uint64_t message_id,
GET_CURRENT_PACKET, "SMB2_COM_READ_REQ: store failed\n");
delete read_request;
}
- Dce2Smb2FileTracker* file_tracker = find_file(file_id);
+ do_not_delete_tree = true;
+ Dce2Smb2FileTrackerPtr file_tracker = find_file(file_id);
Dce2Smb2SessionData* current_flow = parent_session->get_flow(current_flow_key);
if (file_tracker)
{
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL,
GET_CURRENT_PACKET, "SMB2_COM_READ_REQ: start accepting Raw Data\n");
- file_tracker->accept_raw_data_from(current_flow,offset);
+ file_tracker->accept_raw_data_from(current_flow,offset, file_tracker);
}
else
{
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL,
GET_CURRENT_PACKET, "SMB2_COM_READ_REQ: file tracker missing\n");
}
+ do_not_delete_tree = false;
}
void Dce2Smb2TreeTracker::process_write_request(const uint64_t message_id,
delete write_request;
}
const uint8_t* file_data = (const uint8_t*)write_req_hdr + SMB2_WRITE_REQUEST_STRUC_SIZE - 1;
- Dce2Smb2FileTracker* file_tracker = find_file(file_id);
+ do_not_delete_tree = true;
+ Dce2Smb2FileTrackerPtr file_tracker = find_file(file_id);
if (file_tracker)
{
file_tracker->set_direction(FILE_UPLOAD);
{
if ((uint32_t)data_size < alignedNtohl((const uint32_t*)&(write_req_hdr->length)))
{
- file_tracker->accept_raw_data_from(current_flow);
+ file_tracker->accept_raw_data_from(current_flow, 0, file_tracker);
}
}
}
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL,
GET_CURRENT_PACKET,"SMB2_COM_WRITE_REQ: file tracker missing\n");
}
+ do_not_delete_tree = false;
}
void Dce2Smb2TreeTracker::process_ioctl_command(const uint8_t command_type,
{
data_size = UINT16_MAX;
}
-
- DCE2_CoProcess(current_flow->get_dce2_session_data(), co_tracker, file_data, data_size);
+ if (co_tracker)
+ {
+ parent_session->co_tracker_mutex.lock();
+ DCE2_CoProcess(current_flow->get_dce2_session_data(), co_tracker, file_data, data_size);
+ parent_session->co_tracker_mutex.unlock();
+ }
}
void Dce2Smb2TreeTracker::process(uint16_t command, uint8_t command_type,
dce2_smb_stats.v2_read_err_resp++;
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL,
GET_CURRENT_PACKET, "%s_RESP: error\n", smb2_command_string[command]);
+ do_not_delete_tree = true;
Dce2Smb2RequestTracker* request = find_request(message_id, current_flow_key);
if (request)
- close_file(request->get_file_id());
+ close_file(request->get_file_id(), true);
+ do_not_delete_tree = false;
}
else if (SMB2_CMD_TYPE_REQUEST == command_type)
process_read_request(message_id, current_flow_key, smb_header);
dce2_smb_stats.v2_wrt_err_resp++;
SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL,
GET_CURRENT_PACKET, "%s_RESP: error\n", smb2_command_string[command]);
+ do_not_delete_tree = true;
Dce2Smb2RequestTracker* request = find_request(message_id, current_flow_key);
if (request)
- close_file(request->get_file_id());
+ close_file(request->get_file_id(), true);
+ do_not_delete_tree = false;
}
else if (SMB2_CMD_TYPE_REQUEST == command_type)
process_write_request(message_id, current_flow_key, smb_header, end);
remove_request(message_id, current_flow_key);
}
-Dce2Smb2TreeTracker::~Dce2Smb2TreeTracker()
+Dce2Smb2TreeTracker::~Dce2Smb2TreeTracker(void)
{
- if (smb_module_is_up and (is_packet_thread()))
- {
- SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL,
- GET_CURRENT_PACKET, "tree tracker %" PRIu32 " terminating\n", tree_id);
- }
+ if (do_not_delete_tree == true)
+ return;
if (co_tracker != nullptr)
{
if (active_requests.size())
{
- if (smb_module_is_up and (is_packet_thread()))
- {
- SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL,
- GET_CURRENT_PACKET, "cleanup pending requests for below MIDs:\n");
- }
for (auto it_request : active_requests)
{
- if (smb_module_is_up and (is_packet_thread()))
- {
- SMB_DEBUG(dce_smb_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL,
- GET_CURRENT_PACKET, "mid %" PRIu64 "\n", it_request.first.mid);
- }
delete it_request.second;
}
}
for (auto it_file : opened_files)
{
- delete it_file.second;
+ get_parent()->clean_file_context_from_flow(it_file.second->get_file_id(),
+ it_file.second->get_file_name_hash());
+ it_file.second->set_parent(nullptr);
parent_session->decrease_size(sizeof(Dce2Smb2FileTracker));
}
~Dce2Smb2TreeTracker();
- Dce2Smb2FileTracker* open_file(const uint64_t, const uint32_t);
- void close_file(uint64_t, bool=true);
- Dce2Smb2FileTracker* find_file(uint64_t);
+ Dce2Smb2FileTrackerPtr open_file(const uint64_t, const uint32_t);
+ void close_file(uint64_t, bool);
+ Dce2Smb2FileTrackerPtr find_file(uint64_t);
Dce2Smb2RequestTracker* find_request(const uint64_t, const uint32_t);
void process(uint16_t, uint8_t, const Smb2Hdr*, const uint8_t*, const uint32_t);
Dce2Smb2SessionTracker* get_parent() { return parent_session; }
DCE2_CoTracker* get_cotracker() { return co_tracker; }
uint32_t get_tree_id() { return tree_id; }
uint8_t get_share_type() { return share_type; }
+ std::atomic<bool> do_not_delete_tree { false };
+ void set_parent(Dce2Smb2SessionTracker* session_tracker) { parent_session = session_tracker; }
private:
void process_set_info_request(const Smb2Hdr*);
if (data_len > UINT16_MAX)
data_len = UINT16_MAX;
- DCE2_CoProcess(&ssd->sd, ftracker->fp_co_tracker, data_ptr, (uint16_t)data_len);
+ if (ftracker->fp_co_tracker)
+ DCE2_CoProcess(&ssd->sd, ftracker->fp_co_tracker, data_ptr, (uint16_t)data_len);
if (!ftracker->fp_used)
ftracker->fp_used = true;
// Maximum possible fragment length is 16 bit
if (data_len > UINT16_MAX)
data_len = UINT16_MAX;
-
- DCE2_CoProcess(&ssd->sd, ftracker->fp_co_tracker, data_ptr, (uint16_t)data_len);
+ if (ftracker->fp_co_tracker)
+ DCE2_CoProcess(&ssd->sd, ftracker->fp_co_tracker, data_ptr, (uint16_t)data_len);
}
else
{