From af34cc964ae7667db15d2507f24098c26ba3c664 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sat, 7 Aug 2021 00:00:00 -0500 Subject: [PATCH] library: repair api boo-boo in the 'select' i/f The patch referenced below corrected some flaws in the procps_pids_select implementation. But, there remained one flaw which this commit will now hopefully address. Rather than assume callers wished to select only tasks and not threads meant a command like 'top -H -p 10329' works differently under newlib than release 3.3.17. It fails to honor the '-H' (threads) switch under newlib. So, to fix that oops, we'll allow that select function to get threads or tasks depending on its 'which' parm. Reference(s): . Oct 2015, some flaws corrected commit bc616b361596bc3008800de839b88446508cfdd0 Signed-off-by: Jim Warner --- proc/pids.c | 21 +++++++++++++++++++-- proc/pids.h | 6 ++++-- proc/readproc.c | 6 +++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/proc/pids.c b/proc/pids.c index fae340e0..d7897c5e 100644 --- a/proc/pids.c +++ b/proc/pids.c @@ -1214,11 +1214,27 @@ PROCPS_EXPORT int procps_pids_new ( , __FILE__, PIDS_SELECT_PID, PROC_PID); failed = 1; } + if (PIDS_SELECT_PID_THREADS != PIDS_SELECT_PID + 1) { + fprintf(stderr, "%s: header error: PIDS_SELECT_PID_THREADS = 0x%04x, should be 0x%04x\n" + , __FILE__, PIDS_SELECT_PID_THREADS, PIDS_SELECT_PID + 1); + failed = 1; + } if (PIDS_SELECT_UID != PROC_UID) { fprintf(stderr, "%s: header error: PIDS_SELECT_UID = 0x%04x, PROC_UID = 0x%04x\n" , __FILE__, PIDS_SELECT_UID, PROC_UID); failed = 1; } + if (PIDS_SELECT_UID_THREADS != PIDS_SELECT_UID + 1) { + fprintf(stderr, "%s: header error: PIDS_SELECT_UID_THREADS = 0x%04x, should be 0x%04x\n" + , __FILE__, PIDS_SELECT_UID_THREADS, PIDS_SELECT_UID + 1); + failed = 1; + } + // our select() function & select enumerators assume the following ... + if (PIDS_FETCH_THREADS_TOO != 1) { + fprintf(stderr, "%s: header error: PIDS_FETCH_THREADS_TOO = %d, should be 1\n" + , __FILE__, PIDS_FETCH_THREADS_TOO); + failed = 1; + } if (failed) _Exit(EXIT_FAILURE); #endif @@ -1533,7 +1549,8 @@ PROCPS_EXPORT struct pids_fetch *procps_pids_select ( return NULL; if (numthese < 1 || numthese > FILL_ID_MAX) return NULL; - if (which != PIDS_SELECT_PID && which != PIDS_SELECT_UID) + if ((which != PIDS_SELECT_PID && which != PIDS_SELECT_UID) + && ((which != PIDS_SELECT_PID_THREADS && which != PIDS_SELECT_UID_THREADS))) return NULL; /* with items & numitems technically optional at 'new' time, it's expected 'reset' will have been called -- but just in case ... */ @@ -1547,7 +1564,7 @@ PROCPS_EXPORT struct pids_fetch *procps_pids_select ( if (!pids_oldproc_open(&info->fetch_PT, (info->oldflags | which), ids, numthese)) return NULL; - info->read_something = readproc; + info->read_something = (which & PIDS_FETCH_THREADS_TOO) ? readeither : readproc; rc = pids_stacks_fetch(info); diff --git a/proc/pids.h b/proc/pids.h index a14a28d4..2d6e3359 100644 --- a/proc/pids.h +++ b/proc/pids.h @@ -189,8 +189,10 @@ enum pids_fetch_type { }; enum pids_select_type { - PIDS_SELECT_PID = 0x10000, - PIDS_SELECT_UID = 0x20000 + PIDS_SELECT_PID = 0x10000, + PIDS_SELECT_PID_THREADS = 0x10001, + PIDS_SELECT_UID = 0x20000, + PIDS_SELECT_UID_THREADS = 0x20001 }; enum pids_sort_order { diff --git a/proc/readproc.c b/proc/readproc.c index e52b6a22..66045046 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -1126,7 +1126,7 @@ static proc_t *simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons goto next_proc; if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid)) - goto next_proc; /* not one of the requested uids */ + goto next_proc; /* not one of the requested uids */ p->euid = sb.st_uid; /* need a way to get real uid */ p->egid = sb.st_gid; /* need a way to get real gid */ @@ -1248,8 +1248,8 @@ static proc_t *simple_readtask(PROCTAB *restrict const PT, proc_t *restrict cons if (stat(path, &sb) == -1) /* no such dirent (anymore) */ goto next_task; -// if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid)) -// goto next_task; /* not one of the requested uids */ + if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid)) + goto next_task; /* not one of the requested uids */ t->euid = sb.st_uid; /* need a way to get real uid */ t->egid = sb.st_gid; /* need a way to get real gid */