ps: etime overflow reappeared with rewritten library

uptime, w: report user sessions only; upstream backport of 734930e47
Resolves: RHEL-60826
Resolves: RHEL-141839
This commit is contained in:
Jan Rybar 2026-01-24 20:18:10 +01:00
parent d83883f655
commit 423c7e57f7
3 changed files with 102 additions and 1 deletions

View File

@ -4,7 +4,7 @@
Summary: System and process monitoring utilities
Name: procps-ng
Version: 4.0.4
Release: 10%{?dist}
Release: 11%{?dist}
License: GPL-2.0-or-later AND LGPL-2.0-or-later AND LGPL-2.1-or-later
URL: https://sourceforge.net/projects/procps-ng/
@ -14,6 +14,8 @@ Patch1: osh-findings.patch
Patch2: top-fix-guest-tics.patch
Patch3: free-manpage-overcommit-note.patch
Patch4: sysctl-succ-on-fail.patch
Patch5: ps-etime-overflow.patch
Patch6: uptime-w-user-sessions-only.patch
BuildRequires: make
BuildRequires: ncurses-devel
@ -150,6 +152,12 @@ ln -s %{_bindir}/pidof %{buildroot}%{_sbindir}/pidof
%files i18n -f %{name}.lang
%changelog
* Thu Jan 15 2026 Jan Rybar <jrybar@redhat.com> - 4.0.4-11
- ps: etime overflow reappeared with rewritten library
- uptime, w: report user sessions only; upstream backport of 734930e47
- Resolves: RHEL-60826
- Resolves: RHEL-141839
* Thu Dec 04 2025 Jan Rybar <jrybar@redhat.com> - 4.0.4-10
- sysctl: returns success even on fail bug
- Resolves: RHEL-84138

30
ps-etime-overflow.patch Normal file
View File

@ -0,0 +1,30 @@
diff --git a/library/pids.c b/library/pids.c
index 41673b5..f9f4f8f 100644
--- a/library/pids.c
+++ b/library/pids.c
@@ -284,13 +284,13 @@ REG_set(TICS_USER, ull_int, utime)
setDECL(TICS_USER_C) { (void)I; R->result.ull_int = P->utime + P->cutime; }
setDECL(TIME_ALL) { R->result.real = ((double)P->utime + P->stime) / I->hertz; }
setDECL(TIME_ALL_C) { R->result.real = ((double)P->utime + P->stime + P->cutime + P->cstime) / I->hertz; }
-setDECL(TIME_ELAPSED) { double t = I->boot_tics - P->start_time; if (t > 0) R->result.real = t / I->hertz; }
+setDECL(TIME_ELAPSED) { double t = (double)I->boot_tics - P->start_time; if (t > 0) R->result.real = t / I->hertz; }
setDECL(TIME_START) { R->result.real = (double)P->start_time / I->hertz; }
REG_set(TTY, s_int, tty)
setDECL(TTY_NAME) { char buf[64]; freNAME(str)(R); dev_to_tty(buf, sizeof(buf), P->tty, P->tid, ABBREV_DEV); if (!(R->result.str = strdup(buf))) I->seterr = 1; }
setDECL(TTY_NUMBER) { char buf[64]; freNAME(str)(R); dev_to_tty(buf, sizeof(buf), P->tty, P->tid, ABBREV_DEV|ABBREV_TTY|ABBREV_PTS); if (!(R->result.str = strdup(buf))) I->seterr = 1; }
-setDECL(UTILIZATION) { double t = I->boot_tics - P->start_time; if (t > 0) R->result.real = ((P->utime + P->stime) * 100.0f) / t; }
-setDECL(UTILIZATION_C) { double t = I->boot_tics - P->start_time; if (t > 0) R->result.real = ((P->utime + P->stime + P->cutime + P->cstime) * 100.0f) / t; }
+setDECL(UTILIZATION) { double t = (double)I->boot_tics - P->start_time; if (t > 0) R->result.real = ((P->utime + P->stime) * 100.0f) / t; }
+setDECL(UTILIZATION_C) { double t = (double)I->boot_tics - P->start_time; if (t > 0) R->result.real = ((P->utime + P->stime + P->cutime + P->cstime) * 100.0f) / t; }
REG_set(VM_DATA, ul_int, vm_data)
REG_set(VM_EXE, ul_int, vm_exe)
REG_set(VM_LIB, ul_int, vm_lib)
@@ -304,7 +304,7 @@ REG_set(VM_STACK, ul_int, vm_stack)
REG_set(VM_SWAP, ul_int, vm_swap)
setDECL(VM_USED) { (void)I; R->result.ul_int = P->vm_swap + P->vm_rss; }
REG_set(VSIZE_BYTES, ul_int, vsize)
-setDECL(WCHAN_NAME) { freNAME(str)(R); if (!(R->result.str = strdup(lookup_wchan(P->tid)))) I->seterr = 1;; }
+setDECL(WCHAN_NAME) { freNAME(str)(R); if (!(R->result.str = strdup(lookup_wchan(P->tid)))) I->seterr = 1; }
#undef setDECL
#undef CVT_set

View File

@ -0,0 +1,63 @@
diff --git a/library/uptime.c b/library/uptime.c
index 1826343..d63bde7 100644
--- a/library/uptime.c
+++ b/library/uptime.c
@@ -54,8 +54,31 @@ static int count_users(void)
struct utmp *ut;
#if defined(WITH_SYSTEMD) || defined(WITH_ELOGIND)
- if (sd_booted() > 0)
- return sd_get_sessions(NULL);
+ char **sessions_list;
+ int sessions;
+
+ numuser = 0;
+
+ sessions = sd_get_sessions(&sessions_list);
+
+ if (sessions > 0) {
+ int i;
+
+ for (i = 0; i < sessions; i++) {
+ char *class;
+
+ if (sd_session_get_class(sessions_list[i], &class) < 0)
+ continue;
+
+ if (strncmp(class, "user", 4) == 0) // user, user-early, user-incomplete
+ numuser++;
+ free(class);
+ }
+ for (i = 0; i < sessions; i++)
+ free(sessions_list[i]);
+ free(sessions_list);
+ return numuser;
+ }
#endif
setutent();
diff --git a/src/w.c b/src/w.c
index fd6e75f..c7bd214 100644
--- a/src/w.c
+++ b/src/w.c
@@ -814,11 +814,18 @@ int main(int argc, char **argv)
if (sessions < 0 && sessions != -ENOENT)
error(EXIT_FAILURE, -sessions, _("error getting sessions"));
- if (sessions >= 0) {
+ if (sessions > 0) {
for (int i = 0; i < sessions; i++) {
- char *name;
+ char *class, *name;
int r;
+ if ((r = sd_session_get_class(sessions_list[i], &class)) < 0)
+ error(EXIT_FAILURE, -r, _("session get class failed"));
+ if (strncmp(class, "user", 4) != 0) { // user, user-early, user-incomplete
+ free(class);
+ continue;
+ }
+ free(class);
if ((r = sd_session_get_username(sessions_list[i], &name)) < 0)
error(EXIT_FAILURE, -r, _("get user name failed"));