From abf11d86c5c79d7a643f713ee6a889c615bf6f0f Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 18 Jul 2016 09:51:34 -0700 Subject: [PATCH] Dont sanitize strings filters (#625) * Switch back to erase/remove_if for sanitization. It turns out that with -O3 (release flags), using erase/remove_if with an operator struct is slightly faster than the inline version that was here, as the compiler can inline the operators. It isn't faster with -O2 and is much slower without optimization. Optimize for the release build by adding the operators back. * Whitespace diffs. Making whitespace changes in separate commit. * Make sanitize_string cfgable and off for filters. Modify sinsp_filter_check::extract to take an optional argument sanitize_strings, defaulting to true. It controls whether the filtercheck should sanitize any string arguments when extracting the value from the event. The only place where it is set to false is in sinsp_filter_check::compare(). This means that when comparing events against a filter expression, any string values are not sanitized. They will still be sanitized when the events are displayed. This significantly speeds up users like falco that have complicated filter expressions that run against lots of events. --- userspace/libsinsp/filter.cpp | 3 +- userspace/libsinsp/filterchecks.cpp | 97 ++++++++++++++++++----------- userspace/libsinsp/filterchecks.h | 41 ++++++------ userspace/libsinsp/utils.h | 43 +++++-------- 4 files changed, 98 insertions(+), 86 deletions(-) diff --git a/userspace/libsinsp/filter.cpp b/userspace/libsinsp/filter.cpp index 636521171b..817168a29a 100644 --- a/userspace/libsinsp/filter.cpp +++ b/userspace/libsinsp/filter.cpp @@ -1075,7 +1075,8 @@ bool sinsp_filter_check::flt_compare(cmpop op, ppm_param_type type, void* operan bool sinsp_filter_check::compare(sinsp_evt *evt) { uint32_t evt_val_len=0; - uint8_t* extracted_val = extract(evt, &evt_val_len); + bool sanitize_strings = false; + uint8_t* extracted_val = extract(evt, &evt_val_len, sanitize_strings); if(extracted_val == NULL) { diff --git a/userspace/libsinsp/filterchecks.cpp b/userspace/libsinsp/filterchecks.cpp index f4e42131b9..7857e570bc 100644 --- a/userspace/libsinsp/filterchecks.cpp +++ b/userspace/libsinsp/filterchecks.cpp @@ -161,7 +161,7 @@ sinsp_filter_check* sinsp_filter_check_fd::allocate_new() return (sinsp_filter_check*) new sinsp_filter_check_fd(); } -bool sinsp_filter_check_fd::extract_fdname_from_creator(sinsp_evt *evt, OUT uint32_t* len) +bool sinsp_filter_check_fd::extract_fdname_from_creator(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { const char* resolved_argstr; uint16_t etype = evt->get_type(); @@ -247,7 +247,10 @@ bool sinsp_filter_check_fd::extract_fdname_from_creator(sinsp_evt *evt, OUT uint namelen); m_tstr = fullpath; - sanitize_string(m_tstr); + if(sanitize_strings) + { + sanitize_string(m_tstr); + } return true; } @@ -257,7 +260,7 @@ bool sinsp_filter_check_fd::extract_fdname_from_creator(sinsp_evt *evt, OUT uint } } -uint8_t* sinsp_filter_check_fd::extract_from_null_fd(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_fd::extract_from_null_fd(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { // // Even is there's no fd, we still try to extract a name from exit events that create @@ -268,7 +271,7 @@ uint8_t* sinsp_filter_check_fd::extract_from_null_fd(sinsp_evt *evt, OUT uint32_ { case TYPE_FDNAME: { - if(extract_fdname_from_creator(evt, len) == true) + if(extract_fdname_from_creator(evt, len, sanitize_strings) == true) { *len = m_tstr.size(); return (uint8_t*)m_tstr.c_str(); @@ -280,7 +283,7 @@ uint8_t* sinsp_filter_check_fd::extract_from_null_fd(sinsp_evt *evt, OUT uint32_ } case TYPE_CONTAINERNAME: { - if(extract_fdname_from_creator(evt, len) == true) + if(extract_fdname_from_creator(evt, len, sanitize_strings) == true) { m_tstr = m_tinfo->m_container_id + ':' + m_tstr; *len = m_tstr.size(); @@ -293,9 +296,12 @@ uint8_t* sinsp_filter_check_fd::extract_from_null_fd(sinsp_evt *evt, OUT uint32_ } case TYPE_DIRECTORY: { - if(extract_fdname_from_creator(evt, len) == true) + if(extract_fdname_from_creator(evt, len, sanitize_strings) == true) { - sanitize_string(m_tstr); + if(sanitize_strings) + { + sanitize_string(m_tstr); + } size_t pos = m_tstr.rfind('/'); if(pos != string::npos) @@ -320,9 +326,12 @@ uint8_t* sinsp_filter_check_fd::extract_from_null_fd(sinsp_evt *evt, OUT uint32_ } case TYPE_CONTAINERDIRECTORY: { - if(extract_fdname_from_creator(evt, len) == true) + if(extract_fdname_from_creator(evt, len, sanitize_strings) == true) { - sanitize_string(m_tstr); + if(sanitize_strings) + { + sanitize_string(m_tstr); + } size_t pos = m_tstr.rfind('/'); if(pos != string::npos) @@ -354,9 +363,12 @@ uint8_t* sinsp_filter_check_fd::extract_from_null_fd(sinsp_evt *evt, OUT uint32_ return NULL; } - if(extract_fdname_from_creator(evt, len) == true) + if(extract_fdname_from_creator(evt, len, sanitize_strings) == true) { - sanitize_string(m_tstr); + if(sanitize_strings) + { + sanitize_string(m_tstr); + } size_t pos = m_tstr.rfind('/'); if(pos != string::npos) @@ -428,7 +440,7 @@ uint8_t* sinsp_filter_check_fd::extract_from_null_fd(sinsp_evt *evt, OUT uint32_ } } -uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { ASSERT(evt); @@ -451,7 +463,7 @@ uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) case TYPE_CONTAINERNAME: if(m_fdinfo == NULL) { - return extract_from_null_fd(evt, len); + return extract_from_null_fd(evt, len, sanitize_strings); } if(evt->get_type() == PPME_SOCKET_CONNECT_X) @@ -464,7 +476,7 @@ uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) if(retval < 0) { - return extract_from_null_fd(evt, len); + return extract_from_null_fd(evt, len, sanitize_strings); } } @@ -478,8 +490,11 @@ uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) m_tstr = m_fdinfo->m_name; } - sanitize_string(m_tstr); - *len = m_tstr.size(); + if(sanitize_strings) + { + sanitize_string(m_tstr); + *len = m_tstr.size(); + } return (uint8_t*)m_tstr.c_str(); case TYPE_FDTYPE: @@ -494,7 +509,7 @@ uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) { if(m_fdinfo == NULL) { - return extract_from_null_fd(evt, len); + return extract_from_null_fd(evt, len, sanitize_strings); } if(!(m_fdinfo->is_file() || m_fdinfo->is_directory())) @@ -503,7 +518,10 @@ uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) } m_tstr = m_fdinfo->m_name; - sanitize_string(m_tstr); + if(sanitize_strings) + { + sanitize_string(m_tstr); + } if(m_fdinfo->is_file()) { @@ -533,7 +551,7 @@ uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) { if(m_fdinfo == NULL) { - return extract_from_null_fd(evt, len); + return extract_from_null_fd(evt, len, sanitize_strings); } if(!m_fdinfo->is_file()) @@ -542,7 +560,10 @@ uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) } m_tstr = m_fdinfo->m_name; - sanitize_string(m_tstr); + if(sanitize_strings) + { + sanitize_string(m_tstr); + } size_t pos = m_tstr.rfind('/'); if(pos != string::npos) @@ -563,7 +584,7 @@ uint8_t* sinsp_filter_check_fd::extract(sinsp_evt *evt, OUT uint32_t* len) case TYPE_FDTYPECHAR: if(m_fdinfo == NULL) { - return extract_from_null_fd(evt, len); + return extract_from_null_fd(evt, len, sanitize_strings); } m_tcstr[0] = m_fdinfo->get_typechar(); @@ -1250,7 +1271,8 @@ bool sinsp_filter_check_fd::compare(sinsp_evt *evt) // Standard extract-based fields // uint32_t len; - uint8_t* extracted_val = extract(evt, &len); + bool sanitize_strings = false; + uint8_t* extracted_val = extract(evt, &len, sanitize_strings); if(extracted_val == NULL) { @@ -1545,7 +1567,7 @@ uint8_t* sinsp_filter_check_thread::extract_thread_cpu(sinsp_evt *evt, sinsp_thr return NULL; } -uint8_t* sinsp_filter_check_thread::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_thread::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { sinsp_threadinfo* tinfo = evt->get_thread_info(); @@ -2812,7 +2834,7 @@ uint8_t* sinsp_filter_check_event::extract_error_count(sinsp_evt *evt, OUT uint3 return NULL; } -uint8_t* sinsp_filter_check_event::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_event::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { switch(m_field_id) { @@ -3845,7 +3867,8 @@ bool sinsp_filter_check_event::compare(sinsp_evt *evt) if(m_field_id == TYPE_ARGRAW) { uint32_t len; - uint8_t* extracted_val = extract(evt, &len); + bool sanitize_strings = false; + uint8_t* extracted_val = extract(evt, &len, sanitize_strings); if(extracted_val == NULL) { @@ -3910,7 +3933,7 @@ sinsp_filter_check* sinsp_filter_check_user::allocate_new() return (sinsp_filter_check*) new sinsp_filter_check_user(); } -uint8_t* sinsp_filter_check_user::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_user::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { sinsp_threadinfo* tinfo = evt->get_thread_info(); scap_userinfo* uinfo; @@ -3982,7 +4005,7 @@ sinsp_filter_check* sinsp_filter_check_group::allocate_new() return (sinsp_filter_check*) new sinsp_filter_check_group(); } -uint8_t* sinsp_filter_check_group::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_group::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { sinsp_threadinfo* tinfo = evt->get_thread_info(); @@ -4349,7 +4372,7 @@ uint8_t* sinsp_filter_check_tracer::extract_arg(sinsp_partial_tracer* pae) return (uint8_t*)res; } -uint8_t* sinsp_filter_check_tracer::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_tracer::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { sinsp_tracerparser* eparser; sinsp_threadinfo* tinfo = evt->get_thread_info(); @@ -4818,7 +4841,7 @@ sinsp_filter_check* sinsp_filter_check_evtin::allocate_new() return (sinsp_filter_check*) new sinsp_filter_check_evtin(); } -uint8_t* sinsp_filter_check_evtin::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_evtin::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { return NULL; } @@ -5223,7 +5246,7 @@ int32_t rawstring_check::parse_field_name(const char* str, bool alloc_state) return -1; } -uint8_t* rawstring_check::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* rawstring_check::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { *len = m_text_len; return (uint8_t*)m_text.c_str(); @@ -5265,7 +5288,7 @@ int32_t sinsp_filter_check_syslog::parse_field_name(const char* str, bool alloc_ return res; } -uint8_t* sinsp_filter_check_syslog::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_syslog::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { ASSERT(m_decoder != NULL); if(!m_decoder->is_data_valid()) @@ -5316,7 +5339,7 @@ sinsp_filter_check* sinsp_filter_check_container::allocate_new() return (sinsp_filter_check*) new sinsp_filter_check_container(); } -uint8_t* sinsp_filter_check_container::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_container::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { sinsp_threadinfo* tinfo = evt->get_thread_info(); if(tinfo == NULL) @@ -5456,7 +5479,7 @@ int32_t sinsp_filter_check_reference::parse_field_name(const char* str, bool all return -1; } -uint8_t* sinsp_filter_check_reference::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_reference::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { *len = m_len; return m_val; @@ -5783,7 +5806,7 @@ sinsp_filter_check* sinsp_filter_check_utils::allocate_new() return (sinsp_filter_check*) new sinsp_filter_check_utils(); } -uint8_t* sinsp_filter_check_utils::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_utils::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { switch(m_field_id) { @@ -5824,7 +5847,7 @@ sinsp_filter_check* sinsp_filter_check_fdlist::allocate_new() return (sinsp_filter_check*) new sinsp_filter_check_fdlist(); } -uint8_t* sinsp_filter_check_fdlist::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_fdlist::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { ASSERT(evt); sinsp_evt_param *parinfo; @@ -6199,7 +6222,7 @@ bool sinsp_filter_check_k8s::find_label(const k8s_pair_list& labels, const strin return false; } -uint8_t* sinsp_filter_check_k8s::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_k8s::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { if(m_inspector->m_k8s_client == NULL) { @@ -6614,7 +6637,7 @@ bool sinsp_filter_check_mesos::find_label(const mesos_pair_list& labels, const s return false; } -uint8_t* sinsp_filter_check_mesos::extract(sinsp_evt *evt, OUT uint32_t* len) +uint8_t* sinsp_filter_check_mesos::extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings) { if(!m_inspector || !m_inspector->m_mesos_client) { diff --git a/userspace/libsinsp/filterchecks.h b/userspace/libsinsp/filterchecks.h index 99949ba129..e85d8b30db 100644 --- a/userspace/libsinsp/filterchecks.h +++ b/userspace/libsinsp/filterchecks.h @@ -134,9 +134,10 @@ class sinsp_filter_check virtual const filtercheck_field_info* get_field_info(); // - // Extract the field from the event + // Extract the field from the event. In sanitize_strings is true, any + // string values are sanitized to remove nonprintable characters. // - virtual uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len) = 0; + virtual uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true) = 0; // // Extract the field as json from the event (by default, fall @@ -258,7 +259,7 @@ class sinsp_filter_expression : public sinsp_filter_check return NULL; } - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len) + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true) { ASSERT(false); return NULL; @@ -334,7 +335,7 @@ class sinsp_filter_check_fd : public sinsp_filter_check sinsp_filter_check_fd(); sinsp_filter_check* allocate_new(); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); bool compare_ip(sinsp_evt *evt); bool compare_net(sinsp_evt *evt); bool compare_port(sinsp_evt *evt); @@ -348,8 +349,8 @@ class sinsp_filter_check_fd : public sinsp_filter_check uint32_t m_tbool; private: - uint8_t* extract_from_null_fd(sinsp_evt *evt, OUT uint32_t* len); - bool extract_fdname_from_creator(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract_from_null_fd(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings); + bool extract_fdname_from_creator(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings); bool extract_fd(sinsp_evt *evt); }; @@ -407,7 +408,7 @@ class sinsp_filter_check_thread : public sinsp_filter_check sinsp_filter_check_thread(); sinsp_filter_check* allocate_new(); int32_t parse_field_name(const char* str, bool alloc_state); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); bool compare(sinsp_evt *evt); private: @@ -508,7 +509,7 @@ class sinsp_filter_check_event : public sinsp_filter_check void parse_filter_value(const char* str, uint32_t len, uint8_t *storage, uint32_t storage_len); void validate_filter_value(const char* str, uint32_t len); const filtercheck_field_info* get_field_info(); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); Json::Value extract_as_js(sinsp_evt *evt, OUT uint32_t* len); bool compare(sinsp_evt *evt); @@ -558,7 +559,7 @@ class sinsp_filter_check_user : public sinsp_filter_check sinsp_filter_check_user(); sinsp_filter_check* allocate_new(); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); uint32_t m_uid; string m_strval; @@ -578,7 +579,7 @@ class sinsp_filter_check_group : public sinsp_filter_check sinsp_filter_check_group(); sinsp_filter_check* allocate_new(); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); uint32_t m_gid; string m_name; @@ -620,7 +621,7 @@ class sinsp_filter_check_tracer : public sinsp_filter_check ~sinsp_filter_check_tracer(); sinsp_filter_check* allocate_new(); int32_t parse_field_name(const char* str, bool alloc_state); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); private: int32_t extract_arg(string fldname, string val, OUT const struct ppm_param_info** parinfo); @@ -681,7 +682,7 @@ class sinsp_filter_check_evtin : public sinsp_filter_check ~sinsp_filter_check_evtin(); int32_t parse_field_name(const char* str, bool alloc_state); sinsp_filter_check* allocate_new(); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); bool compare(sinsp_evt *evt); uint64_t m_u64val; @@ -721,7 +722,7 @@ class rawstring_check : public sinsp_filter_check sinsp_filter_check* allocate_new(); void set_text(string text); int32_t parse_field_name(const char* str, bool alloc_state); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); // XXX this is overkill and wasted for most of the fields. // It could be optimized by dynamically allocating the right amount @@ -751,7 +752,7 @@ class sinsp_filter_check_syslog : public sinsp_filter_check sinsp_filter_check_syslog(); sinsp_filter_check* allocate_new(); int32_t parse_field_name(const char* str, bool alloc_state); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); sinsp_decoder_syslog* m_decoder; uint32_t m_gid; @@ -771,7 +772,7 @@ class sinsp_filter_check_container : public sinsp_filter_check sinsp_filter_check_container(); sinsp_filter_check* allocate_new(); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); private: string m_tstr; @@ -802,7 +803,7 @@ class sinsp_filter_check_reference : public sinsp_filter_check m_print_format = print_format; } int32_t parse_field_name(const char* str, bool alloc_state); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); char* tostring_nice(sinsp_evt* evt, uint32_t str_len, uint64_t time_delta); private: @@ -831,7 +832,7 @@ class sinsp_filter_check_utils : public sinsp_filter_check sinsp_filter_check_utils(); sinsp_filter_check* allocate_new(); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); private: uint64_t m_cnt; @@ -855,7 +856,7 @@ class sinsp_filter_check_fdlist : public sinsp_filter_check sinsp_filter_check_fdlist(); sinsp_filter_check* allocate_new(); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); private: string m_strval; @@ -888,7 +889,7 @@ class sinsp_filter_check_k8s : public sinsp_filter_check sinsp_filter_check_k8s(); sinsp_filter_check* allocate_new(); int32_t parse_field_name(const char* str, bool alloc_state); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); private: int32_t extract_arg(const string& fldname, const string& val); @@ -925,7 +926,7 @@ class sinsp_filter_check_mesos : public sinsp_filter_check sinsp_filter_check_mesos(); sinsp_filter_check* allocate_new(); int32_t parse_field_name(const char* str, bool alloc_state); - uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len); + uint8_t* extract(sinsp_evt *evt, OUT uint32_t* len, bool sanitize_strings = true); private: diff --git a/userspace/libsinsp/utils.h b/userspace/libsinsp/utils.h index 11e2f4b19c..5a6325843d 100644 --- a/userspace/libsinsp/utils.h +++ b/userspace/libsinsp/utils.h @@ -101,41 +101,28 @@ class sinsp_utils // little STL thing to sanitize strings /////////////////////////////////////////////////////////////////////////////// -inline bool is_invalid_char(char c) -{ - if(c < -1) - { - return true; - } - - return !isprint((unsigned)c); -} - struct g_invalidchar { bool operator()(char c) const - { - return is_invalid_char(c); + { + if(c < -1) + { + return true; + } + + return !isprint((unsigned)c); } }; inline void sanitize_string(string &str) { - uint32_t j=0, k=0; - - while(k < str.length()) - { - if(is_invalid_char(str[k])) - { - k++; - } - else - { - str[j++] = str[k++]; - } - } - - str.resize(j); + // It turns out with -O3 (release flags) using erase and + // remove_if is slighly faster than the inline version that + // was here. It's not faster for -O2, and is actually much + // slower without optimization. + // + // Optimize for the release case, then. + str.erase(remove_if(str.begin(), str.end(), g_invalidchar()), str.end()); } /////////////////////////////////////////////////////////////////////////////// @@ -350,4 +337,4 @@ struct ci_compare // socket helpers /////////////////////////////////////////////////////////////////////////////// -bool set_socket_blocking(int sock, bool block); \ No newline at end of file +bool set_socket_blocking(int sock, bool block);