Skip to content

Commit 739d3b9

Browse files
LucaGuerrapoiana
authored andcommitted
cleanup(libsinsp): throw exception for invalid parsed string vectors
Signed-off-by: Luca Guerra <[email protected]>
1 parent 3793b10 commit 739d3b9

File tree

7 files changed

+64
-61
lines changed

7 files changed

+64
-61
lines changed

userspace/libsinsp/event.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ limitations under the License.
3232
#include <libsinsp/settings.h>
3333
#include <libsinsp/sinsp_exception.h>
3434
#include <libsinsp/fdinfo.h>
35+
#include <libsinsp/utils.h>
3536

3637
class sinsp;
3738
class sinsp_threadinfo;
@@ -150,6 +151,12 @@ inline std::string_view get_event_param_as<std::string_view>(const sinsp_evt_par
150151
return {param.m_val, string_len};
151152
}
152153

154+
template<>
155+
inline std::vector<std::string> get_event_param_as<std::vector<std::string>>(const sinsp_evt_param& param)
156+
{
157+
return sinsp_split(param.m_val, static_cast<size_t>(param.m_len), '\0');
158+
}
159+
153160
/*!
154161
\brief Event class.
155162
This class is returned by \ref sinsp::next() and encapsulates the state

userspace/libsinsp/parsers.cpp

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,6 @@ bool sinsp_parser::retrieve_enter_event(sinsp_evt *enter_evt, sinsp_evt *exit_ev
940940

941941
void sinsp_parser::parse_clone_exit_caller(sinsp_evt *evt, int64_t child_tid)
942942
{
943-
const sinsp_evt_param* parinfo = nullptr;
944943
uint16_t etype = evt->get_type();
945944
int64_t caller_tid = evt->get_tid();
946945

@@ -1229,8 +1228,7 @@ void sinsp_parser::parse_clone_exit_caller(sinsp_evt *evt, int64_t child_tid)
12291228
child_tinfo->m_exe = evt->get_param(1)->as<std::string_view>();
12301229

12311230
/* args */
1232-
parinfo = evt->get_param(2);
1233-
child_tinfo->set_args(parinfo->m_val, parinfo->m_len);
1231+
child_tinfo->set_args(evt->get_param(2)->as<std::vector<std::string>>());
12341232

12351233
/* comm */
12361234
switch(etype)
@@ -1354,8 +1352,7 @@ void sinsp_parser::parse_clone_exit_caller(sinsp_evt *evt, int64_t child_tid)
13541352
case PPME_SYSCALL_VFORK_20_X:
13551353
case PPME_SYSCALL_CLONE_20_X:
13561354
case PPME_SYSCALL_CLONE3_X:
1357-
parinfo = evt->get_param(14);
1358-
child_tinfo->set_cgroups(parinfo->m_val, parinfo->m_len);
1355+
child_tinfo->set_cgroups(evt->get_param(14)->as<std::vector<std::string>>());
13591356
m_inspector->m_container_manager.resolve_container(child_tinfo.get(), m_inspector->is_live() || m_inspector->is_syscall_plugin());
13601357
break;
13611358
}
@@ -1411,8 +1408,7 @@ void sinsp_parser::parse_clone_exit_caller(sinsp_evt *evt, int64_t child_tid)
14111408
caller_tinfo->m_comm = child_tinfo->m_comm;
14121409

14131410
/* args */
1414-
parinfo = evt->get_param(2);
1415-
caller_tinfo->set_args(parinfo->m_val, parinfo->m_len);
1411+
caller_tinfo->set_args(evt->get_param(2)->as<std::vector<std::string>>());
14161412
}
14171413

14181414
/*=============================== CREATE CHILD ===========================*/
@@ -1459,7 +1455,6 @@ void sinsp_parser::parse_clone_exit_caller(sinsp_evt *evt, int64_t child_tid)
14591455

14601456
void sinsp_parser::parse_clone_exit_child(sinsp_evt *evt)
14611457
{
1462-
const sinsp_evt_param *parinfo = nullptr;
14631458
uint16_t etype = evt->get_type();
14641459
int64_t child_tid = evt->get_tid();
14651460

@@ -1688,8 +1683,7 @@ void sinsp_parser::parse_clone_exit_child(sinsp_evt *evt)
16881683
}
16891684

16901685
/* args */
1691-
parinfo = evt->get_param(2);
1692-
child_tinfo->set_args(parinfo->m_val, parinfo->m_len);
1686+
child_tinfo->set_args(evt->get_param(2)->as<std::vector<std::string>>());
16931687

16941688
if(valid_lookup_thread)
16951689
{
@@ -1799,8 +1793,7 @@ void sinsp_parser::parse_clone_exit_child(sinsp_evt *evt)
17991793
lookup_tinfo->m_comm = child_tinfo->m_comm;
18001794

18011795
/* args */
1802-
parinfo = evt->get_param(2);
1803-
lookup_tinfo->set_args(parinfo->m_val, parinfo->m_len);
1796+
lookup_tinfo->set_args(evt->get_param(2)->as<std::vector<std::string>>());
18041797
}
18051798
}
18061799

@@ -1904,8 +1897,7 @@ void sinsp_parser::parse_clone_exit_child(sinsp_evt *evt)
19041897
case PPME_SYSCALL_VFORK_20_X:
19051898
case PPME_SYSCALL_CLONE_20_X:
19061899
case PPME_SYSCALL_CLONE3_X:
1907-
parinfo = evt->get_param(14);
1908-
child_tinfo->set_cgroups(parinfo->m_val, parinfo->m_len);
1900+
child_tinfo->set_cgroups(evt->get_param(14)->as<std::vector<std::string>>());
19091901
m_inspector->m_container_manager.resolve_container(child_tinfo.get(), m_inspector->is_live());
19101902
break;
19111903
}
@@ -2080,8 +2072,7 @@ void sinsp_parser::parse_execve_exit(sinsp_evt *evt)
20802072
}
20812073

20822074
// Get the command arguments
2083-
parinfo = evt->get_param(2);
2084-
evt->get_tinfo()->set_args(parinfo->m_val, parinfo->m_len);
2075+
evt->get_tinfo()->set_args(evt->get_param(2)->as<std::vector<std::string>>());
20852076

20862077
// Get the pid
20872078
evt->get_tinfo()->m_pid = evt->get_param(4)->as<uint64_t>();
@@ -2168,8 +2159,7 @@ void sinsp_parser::parse_execve_exit(sinsp_evt *evt)
21682159
//
21692160
// Set cgroups and heuristically detect container id
21702161
//
2171-
parinfo = evt->get_param(14);
2172-
evt->get_tinfo()->set_cgroups(parinfo->m_val, parinfo->m_len);
2162+
evt->get_tinfo()->set_cgroups(evt->get_param(14)->as<std::vector<std::string>>());
21732163

21742164
//
21752165
// Resync container status after an execve, we need to do it

userspace/libsinsp/test/sinsp_utils.ut.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,14 @@ TEST(sinsp_utils_test, concatenate_paths)
197197
res = sinsp_utils::concatenate_paths(path1, path2);
198198
EXPECT_EQ("/root/c:/hello/world", res); */
199199
}
200+
201+
TEST(sinsp_utils_test, sinsp_split_buf)
202+
{
203+
const char *in = "hello\0world\0";
204+
size_t len = 12;
205+
auto split = sinsp_split(in, len, '\0');
206+
207+
EXPECT_EQ(split.size(), 2);
208+
EXPECT_EQ(split[0], "hello");
209+
EXPECT_EQ(split[1], "world");
210+
}

userspace/libsinsp/threadinfo.cpp

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -616,14 +616,12 @@ std::string sinsp_threadinfo::get_exepath() const
616616

617617
void sinsp_threadinfo::set_args(const char* args, size_t len)
618618
{
619-
m_args.clear();
619+
set_args(sinsp_split(args, len, '\0'));
620+
}
620621

621-
size_t offset = 0;
622-
while(offset < len)
623-
{
624-
m_args.push_back(args + offset);
625-
offset += m_args.back().length() + 1;
626-
}
622+
void sinsp_threadinfo::set_args(std::vector<std::string> args)
623+
{
624+
m_args = args;
627625
}
628626

629627
void sinsp_threadinfo::set_env(const char* env, size_t len)
@@ -641,32 +639,7 @@ void sinsp_threadinfo::set_env(const char* env, size_t len)
641639
}
642640
}
643641

644-
m_env.clear();
645-
size_t offset = 0;
646-
while(offset < len)
647-
{
648-
const char* left = env + offset;
649-
// environment string may actually be shorter than indicated by len
650-
// if the rest is empty, we bail out early
651-
if(!strlen(left))
652-
{
653-
size_t sz = len - offset;
654-
void* zero = calloc(sz, sizeof(char));
655-
if(zero == NULL)
656-
{
657-
throw sinsp_exception("memory allocation error in sinsp_threadinfo::set_env");
658-
}
659-
if(!memcmp(left, zero, sz))
660-
{
661-
free(zero);
662-
return;
663-
}
664-
free(zero);
665-
}
666-
m_env.push_back(left);
667-
668-
offset += m_env.back().length() + 1;
669-
}
642+
m_env = sinsp_split(env, len, '\0');
670643
}
671644

672645
bool sinsp_threadinfo::set_env_from_proc() {
@@ -756,24 +729,25 @@ std::string sinsp_threadinfo::concatenate_all_env()
756729
}
757730

758731
void sinsp_threadinfo::set_cgroups(const char* cgroups, size_t len)
732+
{
733+
set_cgroups(sinsp_split(cgroups, len, '\0'));
734+
}
735+
736+
void sinsp_threadinfo::set_cgroups(std::vector<std::string> cgroups)
759737
{
760738
decltype(m_cgroups) tmp_cgroups(new cgroups_t);
761739

762-
size_t offset = 0;
763-
while(offset < len)
740+
for( auto &def : cgroups)
764741
{
765-
const char* str = cgroups + offset;
766-
const char* sep = strrchr(str, '=');
767-
if(sep == NULL)
742+
std::string::size_type eq_pos = def.find("=");
743+
if (eq_pos == std::string::npos)
768744
{
769-
ASSERT(false);
770745
return;
771746
}
772747

773-
std::string subsys(str, sep - str);
774-
std::string cgroup(sep + 1);
748+
std::string subsys = def.substr(0, eq_pos);
749+
std::string cgroup = def.substr(eq_pos + 1);
775750

776-
size_t subsys_length = subsys.length();
777751
size_t pos = subsys.find("_cgroup");
778752
if(pos != std::string::npos)
779753
{
@@ -797,7 +771,6 @@ void sinsp_threadinfo::set_cgroups(const char* cgroups, size_t len)
797771
}
798772

799773
tmp_cgroups->push_back(std::make_pair(subsys, cgroup));
800-
offset += subsys_length + 1 + cgroup.length() + 1;
801774
}
802775

803776
m_cgroups.swap(tmp_cgroups);

userspace/libsinsp/threadinfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,8 +638,10 @@ class SINSP_PUBLIC sinsp_threadinfo : public libsinsp::state::table_entry
638638
void remove_fd(int64_t fd);
639639
void update_cwd(std::string_view cwd);
640640
void set_args(const char* args, size_t len);
641+
void set_args(std::vector<std::string> args);
641642
void set_env(const char* env, size_t len);
642643
void set_cgroups(const char* cgroups, size_t len);
644+
void set_cgroups(std::vector<std::string> cgroups);
643645
bool is_lastevent_data_valid() const;
644646
inline void set_lastevent_data_validity(bool isvalid)
645647
{

userspace/libsinsp/utils.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,24 @@ std::vector<std::string> sinsp_split(const std::string &s, char delim)
13851385
return res;
13861386
}
13871387

1388+
std::vector<std::string> sinsp_split(const char *buf, size_t len, char delim)
1389+
{
1390+
if(len == 0)
1391+
{
1392+
return {};
1393+
}
1394+
1395+
if(buf[len - 1] != '\0')
1396+
{
1397+
throw sinsp_exception("expected a NUL-terminated buffer of size " +
1398+
std::to_string(len) + ", which instead ends with " +
1399+
std::to_string(buf[len - 1]));
1400+
}
1401+
1402+
std::string s {buf, len - 1};
1403+
return sinsp_split(s, delim);
1404+
}
1405+
13881406
//
13891407
// trim from start
13901408
//

userspace/libsinsp/utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ limitations under the License.
2626

2727
#include <algorithm>
2828
#include <cctype>
29+
#include <cstddef>
2930
#include <cstring>
3031
#include <list>
3132
#include <locale>
@@ -257,6 +258,7 @@ const char* print_format_to_string(ppm_print_format fmt);
257258
// String helpers
258259
///////////////////////////////////////////////////////////////////////////////
259260
std::vector<std::string> sinsp_split(const std::string& s, char delim);
261+
std::vector<std::string> sinsp_split(const char *buf, size_t len, char delim);
260262

261263
template<typename It>
262264
std::string sinsp_join(It begin, It end, char delim)

0 commit comments

Comments
 (0)