Skip to content

Commit 567c2e2

Browse files
author
Mark Stemm
authored
Fix pgid ns (#1080)
* Rename pgid to vpgid to reflect it's in-namespace #1044 added tracking of a process's process group id (pgid). However, this change didn't compeltely handle process group ids in a namespace. When reading process information from /proc, it was using the process group id from the global namespace. When tracking execve()s and setpgid()s it would take the pgid from the namespace of the calling process. To fix this, define the pgid to be the pgid from its current pid namespace. And to make this clear, rename it to vpgid everywhere. This commit handles renaming the variable at the scap/sinsp levels. Other changes will fix setpgid() handling to handle cases when it's called in a pid namespace. * Rename the proc.pgid filtercheck to proc.vpgid This reflects its real meaning (from the namespace) * Removing event parsing for setpgid This means that if a setpgid occurs, the pgid of the process won't be in-sync again until the next execve(), where the process's pgid is returned by the driver in the exit event. However, we expect that this will cover most cases, and is dramatically simpler. * Fix logic for setting vpgid Comment was right, but test was backwards.
1 parent 8703445 commit 567c2e2

File tree

9 files changed

+38
-90
lines changed

9 files changed

+38
-90
lines changed

userspace/libscap/scap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ typedef struct scap_threadinfo
206206
uint64_t pid; ///< The id of the process containing this thread. In single thread processes, this is equal to tid.
207207
uint64_t ptid; ///< The id of the thread that created this thread.
208208
uint64_t sid; ///< The session id of the process containing this thread.
209-
uint64_t pgid; ///< The process group of this thread.
209+
uint64_t vpgid; ///< The process group of this thread, as seen from its current pid namespace
210210
char comm[SCAP_MAX_PATH_SIZE+1]; ///< Command name (e.g. "top")
211211
char exe[SCAP_MAX_PATH_SIZE+1]; ///< argv[0] (e.g. "sshd: user@pts/4")
212212
char exepath[SCAP_MAX_PATH_SIZE+1]; ///< full executable path

userspace/libscap/scap_procs.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ int32_t scap_proc_fill_info_from_stats(char* procdirname, struct scap_threadinfo
6767
uint64_t vtid;
6868
int64_t sid;
6969
int64_t pgid;
70+
int64_t vpgid;
7071
uint32_t vmsize_kb;
7172
uint32_t vmrss_kb;
7273
uint32_t vmswap_kb;
@@ -80,7 +81,7 @@ int32_t scap_proc_fill_info_from_stats(char* procdirname, struct scap_threadinfo
8081
tinfo->uid = (uint32_t)-1;
8182
tinfo->ptid = (uint32_t)-1LL;
8283
tinfo->sid = 0;
83-
tinfo->pgid = 0;
84+
tinfo->vpgid = 0;
8485
tinfo->vmsize_kb = 0;
8586
tinfo->vmrss_kb = 0;
8687
tinfo->vmswap_kb = 0;
@@ -190,6 +191,14 @@ int32_t scap_proc_fill_info_from_stats(char* procdirname, struct scap_threadinfo
190191
tinfo->vtid = tinfo->tid;
191192
}
192193
}
194+
else if(strstr(line, "NSpgid:") == line)
195+
{
196+
nfound++;
197+
if(sscanf(line, "NSpgid: %*u %" PRIu64, &vpgid) == 1)
198+
{
199+
tinfo->vpgid = vpgid;
200+
}
201+
}
193202
else if(strstr(line, "NStgid:") == line)
194203
{
195204
nfound++;
@@ -203,13 +212,13 @@ int32_t scap_proc_fill_info_from_stats(char* procdirname, struct scap_threadinfo
203212
}
204213
}
205214

206-
if(nfound == 8)
215+
if(nfound == 9)
207216
{
208217
break;
209218
}
210219
}
211220

212-
ASSERT(nfound == 8 || nfound == 6 || nfound == 5);
221+
ASSERT(nfound == 9 || nfound == 6 || nfound == 5);
213222

214223
fclose(f);
215224

@@ -260,7 +269,14 @@ int32_t scap_proc_fill_info_from_stats(char* procdirname, struct scap_threadinfo
260269
tinfo->pfmajor = pfmajor;
261270
tinfo->pfminor = pfminor;
262271
tinfo->sid = (uint64_t) sid;
263-
tinfo->pgid = (uint64_t) pgid;
272+
273+
// If we did not find vpgid above, set it to pgid from the
274+
// global namespace.
275+
if(tinfo->vpgid == 0)
276+
{
277+
tinfo->vpgid = pgid;
278+
}
279+
264280
tinfo->tty = tty;
265281

266282
fclose(f);

userspace/libscap/scap_savefile.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ int32_t scap_write_proclist_entry(scap_t *handle, scap_dumper_t *d, struct scap_
290290
scap_dump_write(d, &(tinfo->pid), sizeof(uint64_t)) != sizeof(uint64_t) ||
291291
scap_dump_write(d, &(tinfo->ptid), sizeof(uint64_t)) != sizeof(uint64_t) ||
292292
scap_dump_write(d, &(tinfo->sid), sizeof(uint64_t)) != sizeof(uint64_t) ||
293-
scap_dump_write(d, &(tinfo->pgid), sizeof(uint64_t)) != sizeof(uint64_t) ||
293+
scap_dump_write(d, &(tinfo->vpgid), sizeof(uint64_t)) != sizeof(uint64_t) ||
294294
scap_dump_write(d, &commlen, sizeof(uint16_t)) != sizeof(uint16_t) ||
295295
scap_dump_write(d, tinfo->comm, commlen) != commlen ||
296296
scap_dump_write(d, &exelen, sizeof(uint16_t)) != sizeof(uint16_t) ||
@@ -347,7 +347,7 @@ static int32_t scap_write_proclist(scap_t *handle, scap_dumper_t *d)
347347
sizeof(uint64_t) + // pid
348348
sizeof(uint64_t) + // ptid
349349
sizeof(uint64_t) + // sid
350-
sizeof(uint64_t) + // pgid
350+
sizeof(uint64_t) + // vpgid
351351
2 + strnlen(tinfo->comm, SCAP_MAX_PATH_SIZE) +
352352
2 + strnlen(tinfo->exe, SCAP_MAX_PATH_SIZE) +
353353
2 + strnlen(tinfo->exepath, SCAP_MAX_PATH_SIZE) +
@@ -1074,7 +1074,7 @@ static int32_t scap_read_proclist(scap_t *handle, gzFile f, uint32_t block_lengt
10741074
tinfo.filtered_out = 0;
10751075
tinfo.root[0] = 0;
10761076
tinfo.sid = -1;
1077-
tinfo.pgid = -1;
1077+
tinfo.vpgid = -1;
10781078
tinfo.clone_ts = 0;
10791079
tinfo.tty = 0;
10801080
tinfo.exepath[0] = 0;
@@ -1131,7 +1131,7 @@ static int32_t scap_read_proclist(scap_t *handle, gzFile f, uint32_t block_lengt
11311131
}
11321132

11331133
//
1134-
// pgid
1134+
// vpgid
11351135
//
11361136
switch(block_type)
11371137
{
@@ -1147,7 +1147,7 @@ static int32_t scap_read_proclist(scap_t *handle, gzFile f, uint32_t block_lengt
11471147
case PL_BLOCK_TYPE_V7:
11481148
break;
11491149
case PL_BLOCK_TYPE_V8:
1150-
readsize = gzread(f, &(tinfo.pgid), sizeof(uint64_t));
1150+
readsize = gzread(f, &(tinfo.vpgid), sizeof(uint64_t));
11511151
CHECK_READ_SIZE(readsize, sizeof(uint64_t));
11521152

11531153
totreadsize += readsize;

userspace/libsinsp/filterchecks.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,7 @@ const filtercheck_field_info sinsp_filter_check_thread_fields[] =
13531353
{PT_INT32, EPF_NONE, PF_ID, "proc.tty", "The controlling terminal of the process. 0 for processes without a terminal."},
13541354
{PT_CHARBUF, EPF_NONE, PF_NA, "proc.exepath", "The full executable path of the process."},
13551355
{PT_CHARBUF, EPF_TABLE_ONLY, PF_NA, "thread.nametid", "this field chains the process name and tid of a thread and can be used as a specific identifier of a thread for a specific execve."},
1356-
{PT_INT64, EPF_NONE, PF_ID, "proc.pgid", "the process group id of the process generating the event."},
1356+
{PT_INT64, EPF_NONE, PF_ID, "proc.vpgid", "the process group id of the process generating the event, as seen from its current PID namespace."},
13571357
};
13581358

13591359
sinsp_filter_check_thread::sinsp_filter_check_thread()
@@ -1629,8 +1629,8 @@ uint8_t* sinsp_filter_check_thread::extract(sinsp_evt *evt, OUT uint32_t* len, b
16291629
RETURN_EXTRACT_VAR(tinfo->m_pid);
16301630
case TYPE_SID:
16311631
RETURN_EXTRACT_VAR(tinfo->m_sid);
1632-
case TYPE_PGID:
1633-
RETURN_EXTRACT_VAR(tinfo->m_pgid);
1632+
case TYPE_VPGID:
1633+
RETURN_EXTRACT_VAR(tinfo->m_vpgid);
16341634
case TYPE_SNAME:
16351635
{
16361636
//

userspace/libsinsp/filterchecks.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ class sinsp_filter_check_thread : public sinsp_filter_check
376376
TYPE_TTY = 42,
377377
TYPE_EXEPATH = 43,
378378
TYPE_NAMETID = 44,
379-
TYPE_PGID = 45,
379+
TYPE_VPGID = 45,
380380
};
381381

382382
sinsp_filter_check_thread();

userspace/libsinsp/parsers.cpp

Lines changed: 4 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,6 @@ void sinsp_parser::process_event(sinsp_evt *evt)
465465
case PPME_SYSCALL_SETSID_X:
466466
parse_setsid_exit(evt);
467467
break;
468-
case PPME_SYSCALL_SETPGID_X:
469-
parse_setpgid_exit(evt);
470-
break;
471468
default:
472469
break;
473470
}
@@ -1140,7 +1137,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
11401137
tinfo.m_sid = ptinfo->m_sid;
11411138

11421139
// Copy the process group id from the parent
1143-
tinfo.m_pgid = ptinfo->m_pgid;
1140+
tinfo.m_vpgid = ptinfo->m_vpgid;
11441141

11451142
tinfo.m_tty = ptinfo->m_tty;
11461143
}
@@ -1176,7 +1173,7 @@ void sinsp_parser::parse_clone_exit(sinsp_evt *evt)
11761173
tinfo.m_args = ptinfo->m_args;
11771174
tinfo.m_root = ptinfo->m_root;
11781175
tinfo.m_sid = ptinfo->m_sid;
1179-
tinfo.m_pgid = ptinfo->m_pgid;
1176+
tinfo.m_vpgid = ptinfo->m_vpgid;
11801177
tinfo.m_tty = ptinfo->m_tty;
11811178
}
11821179
else
@@ -1715,10 +1712,10 @@ void sinsp_parser::parse_execve_exit(sinsp_evt *evt)
17151712
case PPME_SYSCALL_EXECVE_18_X:
17161713
break;
17171714
case PPME_SYSCALL_EXECVE_19_X:
1718-
// Get the pgid
1715+
// Get the vpgid
17191716
parinfo = evt->get_param(17);
17201717
ASSERT(parinfo->m_len == sizeof(int64_t));
1721-
evt->m_tinfo->m_pgid = *(int64_t *) parinfo->m_val;
1718+
evt->m_tinfo->m_vpgid = *(int64_t *) parinfo->m_val;
17221719
break;
17231720
default:
17241721
ASSERT(false);
@@ -4493,70 +4490,6 @@ void sinsp_parser::parse_setsid_exit(sinsp_evt *evt)
44934490
}
44944491
}
44954492

4496-
void sinsp_parser::parse_setpgid_exit(sinsp_evt *evt)
4497-
{
4498-
sinsp_evt *enter_evt = &m_tmp_evt;
4499-
sinsp_evt_param *parinfo;
4500-
int64_t retval, pid, pgid;
4501-
4502-
//
4503-
// Extract the return value
4504-
//
4505-
parinfo = evt->get_param(0);
4506-
retval = *(int64_t *)parinfo->m_val;
4507-
ASSERT(parinfo->m_len == sizeof(int64_t));
4508-
4509-
if(retval >= 0 && retrieve_enter_event(enter_evt, evt))
4510-
{
4511-
//
4512-
// Extract the pid
4513-
//
4514-
parinfo = enter_evt->get_param(0);
4515-
pid = *(int64_t *)parinfo->m_val;
4516-
ASSERT(parinfo->m_len == sizeof(int64_t));
4517-
4518-
//
4519-
// Extract the pgid
4520-
//
4521-
parinfo = enter_evt->get_param(1);
4522-
pgid = *(int64_t *)parinfo->m_val;
4523-
ASSERT(parinfo->m_len == sizeof(int64_t));
4524-
4525-
//
4526-
// If pid is zero, then the process ID of the calling process is used.
4527-
//
4528-
sinsp_threadinfo* ptinfo = NULL;
4529-
if (pid == 0)
4530-
{
4531-
ptinfo = evt->get_thread_info();
4532-
}
4533-
else
4534-
{
4535-
ptinfo = m_inspector->get_thread(pid, false, true);
4536-
}
4537-
4538-
if(ptinfo == NULL)
4539-
{
4540-
ASSERT(false);
4541-
return;
4542-
}
4543-
4544-
//
4545-
// If pgid is zero, then the PGID of the process specified
4546-
// by pid is made the same as its process ID.
4547-
//
4548-
if (pgid == 0)
4549-
{
4550-
ptinfo->m_pgid = ptinfo->m_pid;
4551-
}
4552-
else
4553-
{
4554-
ptinfo->m_pgid = pgid;
4555-
}
4556-
4557-
}
4558-
}
4559-
45604493
void sinsp_parser::free_event_buffer(uint8_t *ptr)
45614494
{
45624495
if(m_tmp_events_buffer.size() < m_inspector->m_thread_manager->m_threadtable.size())

userspace/libsinsp/parsers.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ class sinsp_parser
141141
#endif
142142
void parse_chroot_exit(sinsp_evt *evt);
143143
void parse_setsid_exit(sinsp_evt *evt);
144-
void parse_setpgid_exit(sinsp_evt *evt);
145144

146145
inline void add_socket(sinsp_evt* evt, int64_t fd, uint32_t domain, uint32_t type, uint32_t protocol);
147146
inline void add_pipe(sinsp_evt *evt, int64_t tid, int64_t fd, uint64_t ino);

userspace/libsinsp/threadinfo.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void sinsp_threadinfo::init()
5959
{
6060
m_pid = (uint64_t) - 1LL;
6161
m_sid = (uint64_t) - 1LL;
62-
m_pgid = (uint64_t) - 1LL;
62+
m_vpgid = (uint64_t) - 1LL;
6363
set_lastevent_data_validity(false);
6464
m_lastevent_type = -1;
6565
m_lastevent_ts = 0;
@@ -374,7 +374,7 @@ void sinsp_threadinfo::init(scap_threadinfo* pi)
374374
m_pid = pi->pid;
375375
m_ptid = pi->ptid;
376376
m_sid = pi->sid;
377-
m_pgid = pi->pgid;
377+
m_vpgid = pi->vpgid;
378378

379379
m_comm = pi->comm;
380380
m_exe = pi->exe;
@@ -1385,7 +1385,7 @@ void sinsp_thread_manager::thread_to_scap(sinsp_threadinfo& tinfo, scap_threadi
13851385
sctinfo->pid = tinfo.m_pid;
13861386
sctinfo->ptid = tinfo.m_ptid;
13871387
sctinfo->sid = tinfo.m_sid;
1388-
sctinfo->pgid = tinfo.m_pgid;
1388+
sctinfo->vpgid = tinfo.m_vpgid;
13891389

13901390
strncpy(sctinfo->comm, tinfo.m_comm.c_str(), SCAP_MAX_PATH_SIZE);
13911391
strncpy(sctinfo->exe, tinfo.m_exe.c_str(), SCAP_MAX_PATH_SIZE);

userspace/libsinsp/threadinfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ class SINSP_PUBLIC sinsp_threadinfo
226226
int64_t m_pid; ///< The id of the process containing this thread. In single thread threads, this is equal to tid.
227227
int64_t m_ptid; ///< The id of the process that started this thread.
228228
int64_t m_sid; ///< The session id of the process containing this thread.
229-
int64_t m_pgid; ///< The process group of this thread.
230229
string m_comm; ///< Command name (e.g. "top")
231230
string m_exe; ///< argv[0] (e.g. "sshd: user@pts/4")
232231
string m_exepath; ///< full executable path
@@ -246,6 +245,7 @@ class SINSP_PUBLIC sinsp_threadinfo
246245
uint64_t m_pfminor; ///< number of minor page faults since start.
247246
int64_t m_vtid; ///< The virtual id of this thread.
248247
int64_t m_vpid; ///< The virtual id of the process containing this thread. In single thread threads, this is equal to vtid.
248+
int64_t m_vpgid; // The virtual process group id, as seen from its pid namespace
249249
string m_root;
250250
size_t m_program_hash;
251251
size_t m_program_hash_falco;

0 commit comments

Comments
 (0)