Skip to content

Commit

Permalink
Add check for "is an open for reading/writing".
Browse files Browse the repository at this point in the history
While working on measuring performance for falco, I found that one of
the rule bottlenecks was checking for an open for reading/open for
writing. With the current libsinsp, you have to do a string comparison
on the flags argument, which can be slow, especially if you have to
check for multiple flags.

Fix this by adding a check evt.is_open_{read,write} that returns a
boolean based on the value of the flags argument to the corresponding
open/openat. This is similar to the current evt.is_io_{read,write}, but
is argument-specific and limited to open/openat calls.
  • Loading branch information
mstemm committed Jun 27, 2016
1 parent adcfd70 commit 8c7f3fb
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
40 changes: 40 additions & 0 deletions userspace/libsinsp/filterchecks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2238,6 +2238,8 @@ const filtercheck_field_info sinsp_filter_check_event_fields[] =
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.net", "the length of the binary data buffer, but only for network I/O events."},
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.net.in", "the length of the binary data buffer, but only for input network I/O events."},
{PT_UINT64, EPF_TABLE_ONLY, PF_DEC, "evt.buflen.net.out", "the length of the binary data buffer, but only for output network I/O events."},
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_open_read", "'true' for open/openat events where the path was opened for reading"},
{PT_BOOL, EPF_NONE, PF_NA, "evt.is_open_write", "'true' for open/openat events where the path was opened for writing"},
};

sinsp_filter_check_event::sinsp_filter_check_event()
Expand Down Expand Up @@ -3741,6 +3743,44 @@ uint8_t* sinsp_filter_check_event::extract(sinsp_evt *evt, OUT uint32_t* len)
}
}

break;
case TYPE_ISOPEN_READ:
case TYPE_ISOPEN_WRITE:
{
uint16_t etype = evt->get_type();

m_u32val = 0;

if(etype == PPME_SYSCALL_OPEN_X ||
etype == PPME_SYSCALL_OPENAT_E)
{
sinsp_evt_param *parinfo;

// Just happens to be the case that
// flags is the 3rd argument for
// both events.
parinfo = evt->get_param(2);
ASSERT(parinfo->m_len == sizeof(uint32_t));
uint32_t flags = *(uint32_t *)parinfo->m_val;

// PPM open flags use 0x11 for
// PPM_O_RDWR, so there's no need to
// check that value explicitly.
if(m_field_id == TYPE_ISOPEN_READ &&
flags & PPM_O_RDONLY)
{
m_u32val = 1;
}

if(m_field_id == TYPE_ISOPEN_WRITE &&
flags & PPM_O_WRONLY)
{
m_u32val = 1;
}
}

return (uint8_t*)&m_u32val;
}
break;
default:
ASSERT(false);
Expand Down
2 changes: 2 additions & 0 deletions userspace/libsinsp/filterchecks.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,8 @@ class sinsp_filter_check_event : public sinsp_filter_check
TYPE_BUFLEN_NET = 57,
TYPE_BUFLEN_NET_IN = 58,
TYPE_BUFLEN_NET_OUT = 59,
TYPE_ISOPEN_READ = 60,
TYPE_ISOPEN_WRITE = 61
};

sinsp_filter_check_event();
Expand Down

0 comments on commit 8c7f3fb

Please sign in to comment.