From 740af9c26b764c5382d6487a754e6814f31974fe Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Nov 30 2023 18:54:58 +0000 Subject: Fix issues with %getncpus sometimes returning 0 on i686 systems Signed-off-by: Stephen Gallagher --- diff --git a/0001-Fix-getncpus-proc-thread-potentially-returning-zero.patch b/0001-Fix-getncpus-proc-thread-potentially-returning-zero.patch new file mode 100644 index 0000000..b8a2e99 --- /dev/null +++ b/0001-Fix-getncpus-proc-thread-potentially-returning-zero.patch @@ -0,0 +1,31 @@ +From 026e7f75e549280d43cdb4c8a1b2faa6e9db0fa3 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Wed, 15 Nov 2023 09:24:28 +0200 +Subject: [PATCH 1/2] Fix %{getncpus proc/thread} potentially returning zero + +Add the missing sanity check/fixup for memory starved systems where +we end up returning zero cpus. Should've been in commit +deaebd0c89a6d453bb971fd8f5a3b858e7a95733 originally. + +Reported in https://issues.redhat.com/browse/RHEL-16557 +--- + rpmio/macro.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/rpmio/macro.c b/rpmio/macro.c +index 1cccaa98a88c56ed27701f820be01c3f8e7615d1..98067442555f7c458ea4976d96b5438db01bd031 100644 +--- a/rpmio/macro.c ++++ b/rpmio/macro.c +@@ -1255,6 +1255,9 @@ static void doGetncpus(MacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parse + if (mcpus < ncpus) + ncpus = mcpus; + } ++ /* Ensure at least one CPU, no matter how starved */ ++ if (ncpus < 1) ++ ncpus = 1; + + sprintf(buf, "%u", ncpus); + mbAppendStr(mb, buf); +-- +2.43.0 + diff --git a/0002-Fix-integer-overflow-in-memory-calculations-on-32bit.patch b/0002-Fix-integer-overflow-in-memory-calculations-on-32bit.patch new file mode 100644 index 0000000..746063e --- /dev/null +++ b/0002-Fix-integer-overflow-in-memory-calculations-on-32bit.patch @@ -0,0 +1,78 @@ +From eb8660e2aae2f0366886e73dc37beb236e89188b Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Thu, 16 Nov 2023 14:22:15 +0200 +Subject: [PATCH 2/2] Fix integer overflow in memory calculations on 32bit + systems + +"long int" on at least x86 Linux is exactly the same as a plain "int", +so calculations can easily overflow. 32bit systems are not expected to +have hundreds of gigabytes of memory but a 32bit process on a x86_64 can +run into all sorts of funny things, such having 500GB system memory. At +which point the type capable of addressing all of process memory is +absolutely useless for calculating the total memory. + +Use uint64_t in the memory calculations to make the size explicit. Of course +one day we may cross that border too, but I hope to be retired by then. + +Fixes https://issues.redhat.com/browse/RHEL-16557 +--- + rpmio/macro.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/rpmio/macro.c b/rpmio/macro.c +index 98067442555f7c458ea4976d96b5438db01bd031..354b06b0ed34c030638788da5d397b7ba108e806 100644 +--- a/rpmio/macro.c ++++ b/rpmio/macro.c +@@ -1177,30 +1177,32 @@ static void doShescape(MacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parse + mbAppend(mb, '\''); + } + +-static unsigned long getmem_total(void) ++static uint64_t getmem_total(void) + { +- unsigned long mem = 0; ++ uint64_t mem = 0; + long int pagesize = sysconf(_SC_PAGESIZE); + long int pages = sysconf(_SC_PHYS_PAGES); + +- if (pagesize < 0) ++ if (pagesize <= 0) + pagesize = 4096; +- if (pages > 0) +- mem = pages * pagesize; ++ if (pages > 0) { ++ /* Cast needed to force 64bit calculation on 32bit systems */ ++ mem = (uint64_t)pages * pagesize; ++ } + + return mem; + } + +-static unsigned long getmem_proc(int thread) ++static uint64_t getmem_proc(int thread) + { +- unsigned long mem = getmem_total(); ++ uint64_t mem = getmem_total(); + /* + * Conservative estimates for thread use on 32bit systems where address + * space is an issue: 2GB for bare metal, 3GB for a 32bit process + * on a 64bit system. + */ + if (thread) { +- unsigned long vmem = mem; ++ uint64_t vmem = mem; + #if __WORDSIZE == 32 + vmem = UINT32_MAX / 2; + #else +@@ -1224,7 +1226,7 @@ static void doGetncpus(MacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parse + const char *arg = argv[1] ? argv[1] : "total"; + char buf[32]; + unsigned int ncpus = getncpus(); +- unsigned long mem = 0; ++ uint64_t mem = 0; + + if (rstreq(arg, "total")) { + /* nothing */ +-- +2.43.0 + diff --git a/rpm.spec b/rpm.spec index 126eb81..f17f918 100644 --- a/rpm.spec +++ b/rpm.spec @@ -27,7 +27,7 @@ %global rpmver 4.19.0 #global snapver rc1 -%global baserelease 2 +%global baserelease 3 %global sover 10 %global srcver %{rpmver}%{?snapver:-%{snapver}} @@ -141,6 +141,8 @@ rpm-4.18.90-weak-user-group.patch # Patches already upstream: # ... rpm-4.19.0-sysusers-fixes.patch +0001-Fix-getncpus-proc-thread-potentially-returning-zero.patch +0002-Fix-integer-overflow-in-memory-calculations-on-32bit.patch # These are not yet upstream rpm-4.7.1-geode-i686.patch @@ -617,6 +619,9 @@ fi %doc %{_defaultdocdir}/rpm/API/ %changelog +* Thu Nov 30 2023 Stephen Gallagher - 4.19.0-3 +- Fix issues with %%getncpus sometimes returning 0 on i686 systems + * Mon Nov 13 2023 Panu Matilainen - 4.19.0-2 - Ensure central package ops log via rpm-plugin-audit recommends (#1476926) - Own our Python module directory (#2248555)