diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h
index 9ce07a58ef..a436913657 100644
--- a/driver/bpf/fillers.h
+++ b/driver/bpf/fillers.h
@@ -1567,6 +1567,7 @@ FILLER(proc_startupdate_3, true)
kgid_t egid;
pid_t vtid;
pid_t vpid;
+ kuid_t loginuid;
/*
* flags
@@ -1688,6 +1689,16 @@ FILLER(proc_startupdate_3, true)
* pgid
*/
res = bpf_val_to_ring_type(data, bpf_task_pgrp_vnr(task), PT_PID);
+ if (res != PPM_SUCCESS)
+ return res;
+
+ /*
+ * loginuid
+ */
+ /* TODO: implement user namespace support */
+ res = bpf_val_to_ring_type(data, task->loginuid.val, PT_INT32);
+ if (res != PPM_SUCCESS)
+ return res;
}
return res;
diff --git a/driver/event_table.c b/driver/event_table.c
index 2e30e885b7..39b401c5e4 100644
--- a/driver/event_table.c
+++ b/driver/event_table.c
@@ -314,7 +314,7 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = {
/* PPME_PAGE_FAULT_E */ {"page_fault", EC_OTHER, EF_SKIPPARSERESET | EF_DROP_FALCO, 3, {{"addr", PT_UINT64, PF_HEX}, {"ip", PT_UINT64, PF_HEX}, {"error", PT_FLAGS32, PF_HEX, pf_flags} } },
/* PPME_PAGE_FAULT_X */ {"NA5", EC_OTHER, EF_UNUSED, 0},
/* PPME_SYSCALL_EXECVE_19_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE, 1, {{"filename", PT_FSPATH, PF_NA} } },
- /* PPME_SYSCALL_EXECVE_19_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE, 18, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA}, {"tty", PT_INT32, PF_DEC}, {"pgid", PT_PID, PF_DEC} } },
+ /* PPME_SYSCALL_EXECVE_19_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE, 19, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA}, {"tty", PT_INT32, PF_DEC}, {"pgid", PT_PID, PF_DEC}, {"loginuid", PT_INT32, PF_DEC} } },
/* PPME_SYSCALL_SETPGID_E */{"setpgid", EC_PROCESS, EF_MODIFIES_STATE, 2, {{"pid", PT_PID, PF_DEC}, {"pgid", PT_PID, PF_DEC} } },
/* PPME_SYSCALL_SETPGID_X */{"setpgid", EC_PROCESS, EF_MODIFIES_STATE, 1, {{"res", PT_PID, PF_DEC} } },
/* PPME_SYSCALL_BPF_E */{"bpf", EC_OTHER, EF_CREATES_FD, 1, {{"cmd", PT_INT64, PF_DEC} } },
diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c
index e595c0f049..e3c3662a2b 100644
--- a/driver/ppm_fillers.c
+++ b/driver/ppm_fillers.c
@@ -36,6 +36,7 @@ along with sysdig. If not, see .
#include
#include
#include
+#include
#ifdef CONFIG_CGROUPS
#include
#endif
@@ -990,6 +991,20 @@ int f_proc_startupdate(struct event_filler_arguments *args)
#endif
if (unlikely(res != PPM_SUCCESS))
return res;
+
+ /*
+ * loginuid
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ val = from_kuid(current_user_ns(), audit_get_loginuid(current));
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+ val = audit_get_loginuid(current);
+#else
+ val = audit_get_loginuid(current->audit_context);
+#endif
+ res = val_to_ring(args, val, 0, false, 0);
+ if (unlikely(res != PPM_SUCCESS))
+ return res;
}
return add_sentinel(args);
diff --git a/userspace/libscap/scap.h b/userspace/libscap/scap.h
index c6b3fe31c5..bb3dac1fa3 100644
--- a/userspace/libscap/scap.h
+++ b/userspace/libscap/scap.h
@@ -240,6 +240,7 @@ typedef struct scap_threadinfo
scap_fdinfo* fdlist; ///< The fd table for this process
uint64_t clone_ts;
int32_t tty;
+ int32_t loginuid; ///< loginuid (auid)
UT_hash_handle hh; ///< makes this structure hashable
}scap_threadinfo;
diff --git a/userspace/libscap/scap_procs.c b/userspace/libscap/scap_procs.c
index e2062c933a..44e67e4c15 100644
--- a/userspace/libscap/scap_procs.c
+++ b/userspace/libscap/scap_procs.c
@@ -472,6 +472,31 @@ int32_t scap_proc_fill_root(struct scap_threadinfo* tinfo, const char* procdirna
}
}
+int32_t scap_proc_fill_loginuid(struct scap_threadinfo* tinfo, const char* procdirname)
+{
+ uint32_t loginuid;
+ char loginuid_path[SCAP_MAX_PATH_SIZE];
+ char line[512];
+ snprintf(loginuid_path, sizeof(loginuid_path), "%sloginuid", procdirname);
+ FILE* f = fopen(loginuid_path, "r");
+ if(f == NULL)
+ {
+ ASSERT(false);
+ return SCAP_FAILURE;
+ }
+ fgets(line, sizeof(line), f);
+ if(sscanf(line, "%" PRId32, &loginuid) == 1)
+ {
+ tinfo->loginuid = loginuid;
+ return SCAP_SUCCESS;
+ }
+ else
+ {
+ ASSERT(false);
+ return SCAP_FAILURE;
+ }
+}
+
//
// Add a process to the list by parsing its entry under /proc
//
@@ -747,6 +772,16 @@ static int32_t scap_proc_add_from_proc(scap_t* handle, uint32_t tid, int parentt
return SCAP_FAILURE;
}
+ //
+ // set the loginuid
+ //
+ if(SCAP_FAILURE == scap_proc_fill_loginuid(tinfo, dir_name))
+ {
+ snprintf(error, SCAP_LASTERR_SIZE, "can't fill loginuid for %s", dir_name);
+ free(tinfo);
+ return SCAP_FAILURE;
+ }
+
if(stat(dir_name, &dirstat) == 0)
{
tinfo->clone_ts = dirstat.st_ctim.tv_sec*1000000000 + dirstat.st_ctim.tv_nsec;
diff --git a/userspace/libscap/scap_savefile.c b/userspace/libscap/scap_savefile.c
index 0ab7b971ff..db799b0a93 100755
--- a/userspace/libscap/scap_savefile.c
+++ b/userspace/libscap/scap_savefile.c
@@ -398,7 +398,8 @@ int32_t scap_write_proclist_entry_bufs(scap_t *handle, scap_dumper_t *d, struct
scap_dump_write(d, &(cgroupslen), sizeof(uint16_t)) != sizeof(uint16_t) ||
scap_dump_writev(d, cgroups, cgroupscnt) != cgroupslen ||
scap_dump_write(d, &rootlen, sizeof(uint16_t)) != sizeof(uint16_t) ||
- scap_dump_write(d, (char *) root, rootlen) != rootlen)
+ scap_dump_write(d, (char *) root, rootlen) != rootlen ||
+ scap_dump_write(d, &(tinfo->loginuid), sizeof(uint32_t)) != sizeof(uint32_t))
{
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "error writing to file (2)");
return SCAP_FAILURE;
@@ -459,7 +460,8 @@ static int32_t scap_write_proclist(scap_t *handle, scap_dumper_t *d)
sizeof(int64_t) + // vtid
sizeof(int64_t) + // vpid
2 + tinfo->cgroups_len +
- 2 + strnlen(tinfo->root, SCAP_MAX_PATH_SIZE));
+ 2 + strnlen(tinfo->root, SCAP_MAX_PATH_SIZE) +
+ sizeof(int32_t)); // loginuid;
lengths[idx++] = il;
totlen += il;
@@ -1217,6 +1219,7 @@ static int32_t scap_read_proclist(scap_t *handle, gzFile f, uint32_t block_lengt
tinfo.clone_ts = 0;
tinfo.tty = 0;
tinfo.exepath[0] = 0;
+ tinfo.loginuid = -1;
//
// len
@@ -1665,6 +1668,17 @@ static int32_t scap_read_proclist(scap_t *handle, gzFile f, uint32_t block_lengt
// ...
// }
+ //
+ // loginuid
+ //
+ if(sub_len && (subreadsize + sizeof(int32_t)) <= sub_len)
+ {
+ readsize = gzread(f, &(tinfo.loginuid), sizeof(int32_t));
+ CHECK_READ_SIZE(readsize, sizeof(uint32_t));
+ subreadsize += readsize;
+ }
+
+
//
// All parsed. Add the entry to the table, or fire the notification callback
//
diff --git a/userspace/libsinsp/filterchecks.cpp b/userspace/libsinsp/filterchecks.cpp
index 4584bae76a..f55268784d 100644
--- a/userspace/libsinsp/filterchecks.cpp
+++ b/userspace/libsinsp/filterchecks.cpp
@@ -4066,6 +4066,8 @@ const filtercheck_field_info sinsp_filter_check_user_fields[] =
{PT_CHARBUF, EPF_NONE, PF_NA, "user.name", "user name."},
{PT_CHARBUF, EPF_NONE, PF_NA, "user.homedir", "home directory of the user."},
{PT_CHARBUF, EPF_NONE, PF_NA, "user.shell", "user's shell."},
+ {PT_INT32, EPF_NONE, PF_ID, "user.loginuid", "audit user id (auid)."},
+ {PT_CHARBUF, EPF_NONE, PF_NA, "user.loginname", "audit user name (auid)."},
};
sinsp_filter_check_user::sinsp_filter_check_user()
@@ -4092,26 +4094,15 @@ uint8_t* sinsp_filter_check_user::extract(sinsp_evt *evt, OUT uint32_t* len, boo
return NULL;
}
- if(m_field_id != TYPE_UID)
+ if(m_field_id != TYPE_UID && m_field_id != TYPE_LOGINUID && m_field_id != TYPE_LOGINNAME)
{
- unordered_map::const_iterator it;
-
ASSERT(m_inspector != NULL);
- const unordered_map* userlist = m_inspector->get_userlist();
-
- if(tinfo->m_uid == 0xffffffff)
- {
- return NULL;
- }
-
- it = userlist->find(tinfo->m_uid);
- if(it == userlist->end())
+ uinfo = m_inspector->get_user(tinfo->m_uid);
+ ASSERT(uinfo != NULL);
+ if(uinfo == NULL)
{
return NULL;
}
-
- uinfo = it->second;
- ASSERT(uinfo != NULL);
}
switch(m_field_id)
@@ -4124,6 +4115,16 @@ uint8_t* sinsp_filter_check_user::extract(sinsp_evt *evt, OUT uint32_t* len, boo
RETURN_EXTRACT_CSTR(uinfo->homedir);
case TYPE_SHELL:
RETURN_EXTRACT_CSTR(uinfo->shell);
+ case TYPE_LOGINUID:
+ RETURN_EXTRACT_VAR(tinfo->m_loginuid);
+ case TYPE_LOGINNAME:
+ ASSERT(m_inspector != NULL);
+ uinfo = m_inspector->get_user(tinfo->m_loginuid);
+ if(uinfo == NULL)
+ {
+ return NULL;
+ }
+ RETURN_EXTRACT_CSTR(uinfo->name);
default:
ASSERT(false);
break;
diff --git a/userspace/libsinsp/filterchecks.h b/userspace/libsinsp/filterchecks.h
index 881f9f2ddf..5ece1555c2 100644
--- a/userspace/libsinsp/filterchecks.h
+++ b/userspace/libsinsp/filterchecks.h
@@ -533,6 +533,8 @@ class sinsp_filter_check_user : public sinsp_filter_check
TYPE_NAME = 1,
TYPE_HOMEDIR = 2,
TYPE_SHELL = 3,
+ TYPE_LOGINUID = 4,
+ TYPE_LOGINNAME = 5,
};
sinsp_filter_check_user();
diff --git a/userspace/libsinsp/parsers.cpp b/userspace/libsinsp/parsers.cpp
index cac1426394..2038f0b21a 100644
--- a/userspace/libsinsp/parsers.cpp
+++ b/userspace/libsinsp/parsers.cpp
@@ -1148,6 +1148,8 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
tinfo->m_tty = ptinfo->m_tty;
+ tinfo->m_loginuid = ptinfo->m_loginuid;
+
if(!(flags & PPM_CL_CLONE_THREAD))
{
tinfo->m_env = ptinfo->m_env;
@@ -1187,6 +1189,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
tinfo->m_sid = ptinfo->m_sid;
tinfo->m_vpgid = ptinfo->m_vpgid;
tinfo->m_tty = ptinfo->m_tty;
+ tinfo->m_loginuid = ptinfo->m_loginuid;
if(!(flags & PPM_CL_CLONE_THREAD))
{
tinfo->m_env = ptinfo->m_env;
@@ -1748,6 +1751,14 @@ void sinsp_parser::parse_execve_exit(sinsp_evt *evt)
// ...
// }
+ // Get the loginuid
+ if(evt->get_num_params() > 17)
+ {
+ parinfo = evt->get_param(18);
+ ASSERT(parinfo->m_len == sizeof(uint32_t));
+ evt->m_tinfo->m_loginuid = *(uint32_t *) parinfo->m_val;
+ }
+
//
// execve starts with a clean fd list, so we get rid of the fd list that clone
// copied from the parent
diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp
index 6d36e328e4..098f847e38 100644
--- a/userspace/libsinsp/sinsp.cpp
+++ b/userspace/libsinsp/sinsp.cpp
@@ -1500,6 +1500,7 @@ threadinfo_map_t::ptr_t sinsp::get_thread_ref(int64_t tid, bool query_os_if_not_
newti->m_uid = 0xffffffff;
newti->m_gid = 0xffffffff;
newti->m_nchilds = 0;
+ newti->m_loginuid = 0xffffffff;
}
//
@@ -1720,6 +1721,23 @@ const unordered_map* sinsp::get_userlist()
return &m_userlist;
}
+scap_userinfo* sinsp::get_user(uint32_t uid)
+{
+ unordered_map::const_iterator it;
+ if(uid == 0xffffffff)
+ {
+ return NULL;
+ }
+
+ it = m_userlist.find(uid);
+ if(it == m_userlist.end())
+ {
+ return NULL;
+ }
+
+ return it->second;
+}
+
const unordered_map* sinsp::get_grouplist()
{
return &m_grouplist;
diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h
index bde742c5c8..adf5cdb61a 100644
--- a/userspace/libsinsp/sinsp.h
+++ b/userspace/libsinsp/sinsp.h
@@ -522,6 +522,18 @@ class SINSP_PUBLIC sinsp
*/
const unordered_map* get_userlist();
+ /*!
+ \brief Lookup for user in the user table.
+
+ \return the \ref scap_userinfo object containing full user information,
+ if user not found, returns NULL.
+
+ \note this call works with file captures as well, because the user
+ table is stored in the trace files. In that case, the returned
+ user list is the one of the machine where the capture happened.
+ */
+ scap_userinfo* get_user(uint32_t uid);
+
/*!
\brief Return the table with all the machine user groups.
diff --git a/userspace/libsinsp/threadinfo.cpp b/userspace/libsinsp/threadinfo.cpp
index 750860d6f0..ee31730a91 100644
--- a/userspace/libsinsp/threadinfo.cpp
+++ b/userspace/libsinsp/threadinfo.cpp
@@ -90,6 +90,7 @@ void sinsp_threadinfo::init()
m_parent_loop_detected = false;
m_tty = 0;
m_blprogram = NULL;
+ m_loginuid = 0;
}
sinsp_threadinfo::~sinsp_threadinfo()
@@ -420,6 +421,7 @@ void sinsp_threadinfo::init(scap_threadinfo* pi)
m_vpid = pi->vpid;
m_clone_ts = pi->clone_ts;
m_tty = pi->tty;
+ m_loginuid = pi->loginuid;
set_cgroups(pi->cgroups, pi->cgroups_len);
m_root = pi->root;
diff --git a/userspace/libsinsp/threadinfo.h b/userspace/libsinsp/threadinfo.h
index ca1350d462..03932007c5 100644
--- a/userspace/libsinsp/threadinfo.h
+++ b/userspace/libsinsp/threadinfo.h
@@ -260,6 +260,7 @@ class SINSP_PUBLIC sinsp_threadinfo
size_t m_program_hash;
size_t m_program_hash_falco;
int32_t m_tty;
+ int32_t m_loginuid; ///< loginuid (auid)
//
// State for multi-event processing