Skip to content

Commit

Permalink
Fix integer overflow in memory calculations on 32bit systems
Browse files Browse the repository at this point in the history
"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
  • Loading branch information
pmatilai committed Nov 27, 2023
1 parent d0e03b2 commit 1cd9f90
Showing 1 changed file with 11 additions and 9 deletions.
20 changes: 11 additions & 9 deletions rpmio/macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -1175,30 +1175,32 @@ static void doShescape(rpmMacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *pa
rpmMacroBufAppend(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
Expand All @@ -1222,7 +1224,7 @@ static void doGetncpus(rpmMacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *pa
const char *arg = (argv && 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 */
Expand Down

0 comments on commit 1cd9f90

Please sign in to comment.