Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update(parsers): Support userspace parsers for memfd_create syscall. #1162

Merged
merged 2 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions driver/event_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,8 @@ const struct ppm_event_info g_event_info[] = {
[PPME_SYSCALL_PRCTL_X] = {"prctl", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"option", PT_ENUMFLAGS32, PF_DEC, prctl_options}, {"arg2_str", PT_CHARBUF, PF_NA}, {"arg2_int", PT_INT64, PF_DEC} } },
[PPME_ASYNCEVENT_E] = {"asyncevent", EC_OTHER | EC_METAEVENT, EF_LARGE_PAYLOAD, 3, {{"plugin_id", PT_UINT32, PF_DEC}, {"name", PT_CHARBUF, PF_NA}, {"data", PT_BYTEBUF, PF_NA} } },
[PPME_ASYNCEVENT_X] = {"NA", EC_UNKNOWN, EF_UNUSED, 0},
[PPME_SYSCALL_MEMFD_CREATE_E] = {"memfd_create", EC_MEMORY | EC_SYSCALL, EF_CREATES_FD, 0},
[PPME_SYSCALL_MEMFD_CREATE_X] = {"memfd_create", EC_MEMORY | EC_SYSCALL, EF_CREATES_FD, 3, {{"fd",PT_FD,PF_DEC},{"name", PT_CHARBUF, PF_NA},{"flags", PT_FLAGS32, PF_HEX, memfd_create_flags} } },
[PPME_SYSCALL_MEMFD_CREATE_E] = {"memfd_create", EC_MEMORY | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 0},
[PPME_SYSCALL_MEMFD_CREATE_X] = {"memfd_create", EC_MEMORY | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"fd",PT_FD,PF_DEC},{"name", PT_CHARBUF, PF_NA},{"flags", PT_FLAGS32, PF_HEX, memfd_create_flags} } },
[PPME_SYSCALL_PIDFD_GETFD_E] = {"pidfd_getfd", EC_PROCESS | EC_SYSCALL, EF_CREATES_FD , 0},
[PPME_SYSCALL_PIDFD_GETFD_X] = {"pidfd_getfd", EC_PROCESS | EC_SYSCALL, EF_CREATES_FD , 4, {{"fd", PT_FD, PF_DEC}, {"pid_fd", PT_FD, PF_DEC}, {"target_fd", PT_FD, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX}}}
};
Expand Down
1 change: 1 addition & 0 deletions userspace/libscap/scap.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ typedef enum scap_fd_type
SCAP_FD_BPF = 17,
SCAP_FD_USERFAULTFD = 18,
SCAP_FD_IOURING = 19,
SCAP_FD_MEMFD = 20
Rohith-Raju marked this conversation as resolved.
Show resolved Hide resolved
}scap_fd_type;

/*!
Expand Down
4 changes: 4 additions & 0 deletions userspace/libsinsp/fdinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ template<> char sinsp_fdinfo_t::get_typechar()
return CHAR_FD_USERFAULTFD;
case SCAP_FD_IOURING:
return CHAR_FD_IO_URING;
case SCAP_FD_MEMFD:
return CHAR_FD_MEMFD;
default:
// ASSERT(false);
return '?';
Expand Down Expand Up @@ -148,6 +150,8 @@ template<> char* sinsp_fdinfo_t::get_typestring()
return (char*)"userfaultfd";
case SCAP_FD_IOURING:
return (char*)"io_uring";
case SCAP_FD_MEMFD:
return (char*)"memfd";
default:
return (char*)"<NA>";
}
Expand Down
1 change: 1 addition & 0 deletions userspace/libsinsp/fdinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class sinsp_protodecoder;
#define CHAR_FD_BPF 'b'
#define CHAR_FD_USERFAULTFD 'u'
#define CHAR_FD_IO_URING 'r'
#define CHAR_FD_MEMFD 'm'

/** @defgroup state State management
* A collection of classes to query process and FD state.
Expand Down
4 changes: 2 additions & 2 deletions userspace/libsinsp/filterchecks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,8 @@ bool sinsp_filter_check_fspath::extract_fspath(sinsp_evt* evt,
const filtercheck_field_info sinsp_filter_check_fd_fields[] =
{
{PT_INT64, EPF_NONE, PF_ID, "fd.num", "FD Number", "the unique number identifying the file descriptor."},
{PT_CHARBUF, EPF_NONE, PF_DEC, "fd.type", "FD Type", "type of FD. Can be 'file', 'directory', 'ipv4', 'ipv6', 'unix', 'pipe', 'event', 'signalfd', 'eventpoll', 'inotify' or 'signalfd'."},
{PT_CHARBUF, EPF_NONE, PF_DEC, "fd.typechar", "FD Type Char", "type of FD as a single character. Can be 'f' for file, 4 for IPv4 socket, 6 for IPv6 socket, 'u' for unix socket, p for pipe, 'e' for eventfd, 's' for signalfd, 'l' for eventpoll, 'i' for inotify, 'b' for bpf, 'u' for userfaultd, 'r' for io_uring, 'o' for unknown."},
{PT_CHARBUF, EPF_NONE, PF_DEC, "fd.type", "FD Type", "type of FD. Can be 'file', 'directory', 'ipv4', 'ipv6', 'unix', 'pipe', 'event', 'signalfd', 'eventpoll', 'inotify' 'signalfd' or 'memfd'."},
{PT_CHARBUF, EPF_NONE, PF_DEC, "fd.typechar", "FD Type Char", "type of FD as a single character. Can be 'f' for file, 4 for IPv4 socket, 6 for IPv6 socket, 'u' for unix socket, p for pipe, 'e' for eventfd, 's' for signalfd, 'l' for eventpoll, 'i' for inotify, 'b' for bpf, 'u' for userfaultd, 'r' for io_uring, 'm' for memfd ,'o' for unknown."},
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.name", "FD Name", "FD full name. If the fd is a file, this field contains the full path. If the FD is a socket, this field contain the connection tuple."},
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.directory", "FD Directory", "If the fd is a file, the directory that contains it."},
{PT_CHARBUF, EPF_NONE, PF_NA, "fd.filename", "FD Filename", "If the fd is a file, the filename without the path."},
Expand Down
52 changes: 52 additions & 0 deletions userspace/libsinsp/parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,9 @@ void sinsp_parser::process_event(sinsp_evt *evt)
case PPME_SYSCALL_SETNS_X:
parse_unshare_setns_exit(evt);
break;
case PPME_SYSCALL_MEMFD_CREATE_X:
parse_memfd_create_exit(evt, SCAP_FD_MEMFD);
break;
case PPME_SYSCALL_CLONE_11_X:
case PPME_SYSCALL_CLONE_16_X:
case PPME_SYSCALL_CLONE_17_X:
Expand Down Expand Up @@ -6025,3 +6028,52 @@ void sinsp_parser::free_event_buffer(uint8_t *ptr)
free(ptr);
}
}

void sinsp_parser::parse_memfd_create_exit(sinsp_evt *evt, scap_fd_type type)
{
sinsp_evt_param* parinfo;
int64_t fd;
char *name;
uint32_t flags;
sinsp_fdinfo_t fdi;


ASSERT(evt->m_tinfo)
if(evt->m_tinfo == nullptr)
{
return;
}

/* ret (fd) */
parinfo = evt->get_param(0);
ASSERT(parinfo->m_len == sizeof(int64_t));
ASSERT(evt->get_param_info(0)->type == PT_FD);
fd = *(int64_t *)parinfo->m_val;

/* name */
parinfo = evt->get_param(1);
Rohith-Raju marked this conversation as resolved.
Show resolved Hide resolved
name = parinfo->m_val;

/* flags */
parinfo = evt->get_param(2);
ASSERT(parinfo->m_len == sizeof(uint32_t));
flags = *(uint32_t *)parinfo->m_val;

if(fd >= 0)
{
fdi.m_type = type;
fdi.add_filename(name);
fdi.m_openflags = flags;
}

if(fdi.m_name == USER_EVT_DEVICE_NAME)
{
fdi.m_flags |= sinsp_fdinfo_t::FLAGS_IS_TRACER_FILE;
}
else
{
fdi.m_flags |= sinsp_fdinfo_t::FLAGS_IS_NOT_TRACER_FD;
}

evt->m_fdinfo = evt->m_tinfo->add_fd(fd, &fdi);
}
1 change: 1 addition & 0 deletions userspace/libsinsp/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class sinsp_parser
void parse_close_enter(sinsp_evt* evt);
void parse_close_exit(sinsp_evt* evt);
void parse_thread_exit(sinsp_evt* evt);
void parse_memfd_create_exit(sinsp_evt* evt, scap_fd_type type);
inline bool detect_and_process_tracer_write(sinsp_evt *evt, int64_t retval, ppm_event_flags eflags);
void parse_fspath_related_exit(sinsp_evt* evt);
inline void parse_rw_exit(sinsp_evt* evt);
Expand Down
19 changes: 19 additions & 0 deletions userspace/libsinsp/test/events_file.ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -625,3 +625,22 @@ TEST_F(sinsp_with_test_input, fchown)
ASSERT_EQ(get_field_as_string(evt, "fd.name"), "/tmp/test");
ASSERT_EQ(get_field_as_string(evt, "fd.num"), "3");
}

TEST_F(sinsp_with_test_input, memfd_create)
{
add_default_init_thread();
open_inspector();
sinsp_evt* evt = NULL;
const char *name = "test_name";
int64_t fd = 4;

add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_MEMFD_CREATE_E, 0);
evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_MEMFD_CREATE_X, 3, fd, name, 0);

ASSERT_EQ(evt->get_type(), PPME_SYSCALL_MEMFD_CREATE_X);
ASSERT_EQ(get_field_as_string(evt, "fd.num"), std::to_string(fd));
ASSERT_EQ(get_field_as_string(evt, "fd.name"), name);
ASSERT_EQ(get_field_as_string(evt, "fd.typechar"), "m");
ASSERT_EQ(get_field_as_string(evt, "fd.type"), "memfd");

}
3 changes: 3 additions & 0 deletions userspace/libsinsp/test/public_sinsp_API/ppm_sc_codes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ const libsinsp::events::set<ppm_event_code> expected_sinsp_state_event_set = {
PPME_SYSCALL_PRCTL_E,
PPME_SYSCALL_PRCTL_X,
PPME_ASYNCEVENT_E,
PPME_SYSCALL_MEMFD_CREATE_E,
PPME_SYSCALL_MEMFD_CREATE_X
};

const libsinsp::events::set<ppm_sc_code> expected_sinsp_state_sc_set = {
Expand Down Expand Up @@ -271,6 +273,7 @@ const libsinsp::events::set<ppm_sc_code> expected_sinsp_state_sc_set = {
PPM_SC_EPOLL_CREATE1,
PPM_SC_SCHED_PROCESS_EXIT,
PPM_SC_PRCTL,
PPM_SC_MEMFD_CREATE
};

const libsinsp::events::set<ppm_event_code> expected_unknown_event_set = {
Expand Down