|
|
740af9 |
From eb8660e2aae2f0366886e73dc37beb236e89188b Mon Sep 17 00:00:00 2001
|
|
|
740af9 |
From: Panu Matilainen <pmatilai@redhat.com>
|
|
|
740af9 |
Date: Thu, 16 Nov 2023 14:22:15 +0200
|
|
|
740af9 |
Subject: [PATCH 2/2] Fix integer overflow in memory calculations on 32bit
|
|
|
740af9 |
systems
|
|
|
740af9 |
|
|
|
740af9 |
"long int" on at least x86 Linux is exactly the same as a plain "int",
|
|
|
740af9 |
so calculations can easily overflow. 32bit systems are not expected to
|
|
|
740af9 |
have hundreds of gigabytes of memory but a 32bit process on a x86_64 can
|
|
|
740af9 |
run into all sorts of funny things, such having 500GB system memory. At
|
|
|
740af9 |
which point the type capable of addressing all of process memory is
|
|
|
740af9 |
absolutely useless for calculating the total memory.
|
|
|
740af9 |
|
|
|
740af9 |
Use uint64_t in the memory calculations to make the size explicit. Of course
|
|
|
740af9 |
one day we may cross that border too, but I hope to be retired by then.
|
|
|
740af9 |
|
|
|
740af9 |
Fixes https://issues.redhat.com/browse/RHEL-16557
|
|
|
740af9 |
---
|
|
|
740af9 |
rpmio/macro.c | 20 +++++++++++---------
|
|
|
740af9 |
1 file changed, 11 insertions(+), 9 deletions(-)
|
|
|
740af9 |
|
|
|
740af9 |
diff --git a/rpmio/macro.c b/rpmio/macro.c
|
|
|
740af9 |
index 98067442555f7c458ea4976d96b5438db01bd031..354b06b0ed34c030638788da5d397b7ba108e806 100644
|
|
|
740af9 |
--- a/rpmio/macro.c
|
|
|
740af9 |
+++ b/rpmio/macro.c
|
|
|
740af9 |
@@ -1177,30 +1177,32 @@ static void doShescape(MacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parse
|
|
|
740af9 |
mbAppend(mb, '\'');
|
|
|
740af9 |
}
|
|
|
740af9 |
|
|
|
740af9 |
-static unsigned long getmem_total(void)
|
|
|
740af9 |
+static uint64_t getmem_total(void)
|
|
|
740af9 |
{
|
|
|
740af9 |
- unsigned long mem = 0;
|
|
|
740af9 |
+ uint64_t mem = 0;
|
|
|
740af9 |
long int pagesize = sysconf(_SC_PAGESIZE);
|
|
|
740af9 |
long int pages = sysconf(_SC_PHYS_PAGES);
|
|
|
740af9 |
|
|
|
740af9 |
- if (pagesize < 0)
|
|
|
740af9 |
+ if (pagesize <= 0)
|
|
|
740af9 |
pagesize = 4096;
|
|
|
740af9 |
- if (pages > 0)
|
|
|
740af9 |
- mem = pages * pagesize;
|
|
|
740af9 |
+ if (pages > 0) {
|
|
|
740af9 |
+ /* Cast needed to force 64bit calculation on 32bit systems */
|
|
|
740af9 |
+ mem = (uint64_t)pages * pagesize;
|
|
|
740af9 |
+ }
|
|
|
740af9 |
|
|
|
740af9 |
return mem;
|
|
|
740af9 |
}
|
|
|
740af9 |
|
|
|
740af9 |
-static unsigned long getmem_proc(int thread)
|
|
|
740af9 |
+static uint64_t getmem_proc(int thread)
|
|
|
740af9 |
{
|
|
|
740af9 |
- unsigned long mem = getmem_total();
|
|
|
740af9 |
+ uint64_t mem = getmem_total();
|
|
|
740af9 |
/*
|
|
|
740af9 |
* Conservative estimates for thread use on 32bit systems where address
|
|
|
740af9 |
* space is an issue: 2GB for bare metal, 3GB for a 32bit process
|
|
|
740af9 |
* on a 64bit system.
|
|
|
740af9 |
*/
|
|
|
740af9 |
if (thread) {
|
|
|
740af9 |
- unsigned long vmem = mem;
|
|
|
740af9 |
+ uint64_t vmem = mem;
|
|
|
740af9 |
#if __WORDSIZE == 32
|
|
|
740af9 |
vmem = UINT32_MAX / 2;
|
|
|
740af9 |
#else
|
|
|
740af9 |
@@ -1224,7 +1226,7 @@ static void doGetncpus(MacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parse
|
|
|
740af9 |
const char *arg = argv[1] ? argv[1] : "total";
|
|
|
740af9 |
char buf[32];
|
|
|
740af9 |
unsigned int ncpus = getncpus();
|
|
|
740af9 |
- unsigned long mem = 0;
|
|
|
740af9 |
+ uint64_t mem = 0;
|
|
|
740af9 |
|
|
|
740af9 |
if (rstreq(arg, "total")) {
|
|
|
740af9 |
/* nothing */
|
|
|
740af9 |
--
|
|
|
740af9 |
2.43.0
|
|
|
740af9 |
|