mirror of https://github.com/xzeldon/htop.git
LinuxProcessList_recurseProcTree: open dirfd first
A process can die between reading the directory listing and opening the directory FD (if HAVE_OPENAT) or /proc files (otherwise) for reading the process data. This race would cause LinuxProcessList_recurseProcTree to remove it from the list immediately, which is unexpected in the "highlight dying processes" mode and can break the tree structure. This patch closes this race in the HAVE_OPENAT case by only accessing the process entry after the directory FD has been opened.
This commit is contained in:
parent
e08eec813c
commit
e07fce7014
|
@ -1446,6 +1446,15 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||||
if (parent && pid == parent->pid)
|
if (parent && pid == parent->pid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENAT
|
||||||
|
int procFd = openat(dirFd, entry->d_name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
|
||||||
|
if (procFd < 0)
|
||||||
|
continue;
|
||||||
|
#else
|
||||||
|
char procFd[4096];
|
||||||
|
xSnprintf(procFd, sizeof(procFd), "%s/%s", dirFd, entry->d_name);
|
||||||
|
#endif
|
||||||
|
|
||||||
bool preExisting;
|
bool preExisting;
|
||||||
Process* proc = ProcessList_getProcess(pl, pid, &preExisting, LinuxProcess_new);
|
Process* proc = ProcessList_getProcess(pl, pid, &preExisting, LinuxProcess_new);
|
||||||
LinuxProcess* lp = (LinuxProcess*) proc;
|
LinuxProcess* lp = (LinuxProcess*) proc;
|
||||||
|
@ -1453,15 +1462,6 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
|
||||||
proc->tgid = parent ? parent->pid : pid;
|
proc->tgid = parent ? parent->pid : pid;
|
||||||
proc->isUserlandThread = proc->pid != proc->tgid;
|
proc->isUserlandThread = proc->pid != proc->tgid;
|
||||||
|
|
||||||
#ifdef HAVE_OPENAT
|
|
||||||
int procFd = openat(dirFd, entry->d_name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
|
|
||||||
if (procFd < 0)
|
|
||||||
goto errorReadingProcess;
|
|
||||||
#else
|
|
||||||
char procFd[4096];
|
|
||||||
xSnprintf(procFd, sizeof(procFd), "%s/%s", dirFd, entry->d_name);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LinuxProcessList_recurseProcTree(this, procFd, "task", proc, period);
|
LinuxProcessList_recurseProcTree(this, procFd, "task", proc, period);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue