#1146373 linux-libc-dev: sbrk(2) allocates more than memory + swap space

Package:
linux-libc-dev
Source:
linux-libc-dev
Description:
Linux support headers for userspace development
Submitter:
Carl Wuebker
Date:
2026-09-25 11:35:02 UTC
Severity:
normal
Tags:
#1146373#5
Date:
2026-08-31 19:23:35 UTC
From:
To:
   The problem is that sbrk(2) checks each new request against the
machine's total RAM + swap space.  It should check each new request
against total RAM + swap space - memory that has already been allocated
to the current process.

Steps to reproduce:
1. Compile & run the program below on a machine with 32 GiB memory & 24
GiB swap
--- eatmem_bad.c
#include <stdio.h>
#include <unistd.h>

intptr_t bigMem = (intptr_t) 128LL*1024*1024*1024;

int main(int argc,char *argv[]) {
     intptr_t i;
     unsigned long long mem;

     if (argc != 1)
         { (void) fprintf(stderr,"Usage: %s\n", argv[0]); return 2; }

     mem=0;
     for (i = bigMem; i >= 16; i /= 2)
         if (sbrk(i) != (void *) -1)
             mem |= i;

     (void) printf("Memory=%llu MiB\n",mem / (1024*1024));

     return 0;
     }
---

Expected (and correct) result:
Memory=56718 MiB

Actual result:
Memory=65535 MiB

#1146373#18
Date:
2026-09-16 18:40:58 UTC
From:
To:
Hello Carl,

I wonder what your actual problem is.

It's quite usual that a process can get more memory assigned than there
is physically available. That's called "overcommitting" if you want to
research about that.

Unless there is a real problem to solve I suggest to either ignore it or
discuss with upstream what to do.

Best regards
Uwe

#1146373#23
Date:
2026-09-16 18:40:58 UTC
From:
To:
Hello Carl,

I wonder what your actual problem is.

It's quite usual that a process can get more memory assigned than there
is physically available. That's called "overcommitting" if you want to
research about that.

Unless there is a real problem to solve I suggest to either ignore it or
discuss with upstream what to do.

Best regards
Uwe

#1146373#28
Date:
2026-09-16 20:32:09 UTC
From:
To:
Hi Uwe,
   Thanks for your reply.  The "real problem" comes from the current
situation in CAD, AI & other single programs running on a Linux
machine.  Some programs need a way to find out how much RAM is available
and might use a technique similar to this one, which might report that
almost 2x the available RAM is available because, as the man page says:

"On success, sbrk() returns the previous program break.  (If the break 
was  increased,  then this  value is a pointer to the start of the newly
allocated memory).  On error, (void *) -1 is returned, and errno is set
to ENOMEM."

When I read this, I think "if the memory allocation was unsuccessful,
I'll get an error."  But that's not the case -- I guess that if I ask it
to allocate 128 GBy and get no error, I still need to check the brk(2)
value to see if the memory was allocated.

So, in my mind (but maybe not obvious to others), there is a problem
with 2 solutions -- one is to return an error if the last memory
allocation fails, the other is to update the sbrk(2) documentation to
tell the user that -- even if the sbrk(2) doesn't return an error --
they need to compare the sbrk(2) return value with the last sbrk(2)
value to see if it moved -- if it didn't move, the allocation failed.

Where can I find a reasonably up-to-date copy of Linux's sbrk(2) code? 
I might be better able to understand your comments and/or recommend a
solution if I read that code.

Thanks,

Carl

#1146373#33
Date:
2026-09-16 20:32:09 UTC
From:
To:
Hi Uwe,
   Thanks for your reply.  The "real problem" comes from the current
situation in CAD, AI & other single programs running on a Linux
machine.  Some programs need a way to find out how much RAM is available
and might use a technique similar to this one, which might report that
almost 2x the available RAM is available because, as the man page says:

"On success, sbrk() returns the previous program break.  (If the break 
was  increased,  then this  value is a pointer to the start of the newly
allocated memory).  On error, (void *) -1 is returned, and errno is set
to ENOMEM."

When I read this, I think "if the memory allocation was unsuccessful,
I'll get an error."  But that's not the case -- I guess that if I ask it
to allocate 128 GBy and get no error, I still need to check the brk(2)
value to see if the memory was allocated.

So, in my mind (but maybe not obvious to others), there is a problem
with 2 solutions -- one is to return an error if the last memory
allocation fails, the other is to update the sbrk(2) documentation to
tell the user that -- even if the sbrk(2) doesn't return an error --
they need to compare the sbrk(2) return value with the last sbrk(2)
value to see if it moved -- if it didn't move, the allocation failed.

Where can I find a reasonably up-to-date copy of Linux's sbrk(2) code? 
I might be better able to understand your comments and/or recommend a
solution if I read that code.

Thanks,

Carl

#1146373#38
Date:
2026-09-23 14:19:30 UTC
From:
To:
Hello,

Sounds too hypothetical to me to spend my time on debugging that.

brk() doesn't allocate memory, that's done lazily once the program hits
a page fault.

This is not practical. Please research about "linux overcommit memory"
to learn why the situation is as it is.

Check the libc and kernel source.

Best regards
Uwe

#1146373#43
Date:
2026-09-23 14:19:30 UTC
From:
To:
Hello,

Sounds too hypothetical to me to spend my time on debugging that.

brk() doesn't allocate memory, that's done lazily once the program hits
a page fault.

This is not practical. Please research about "linux overcommit memory"
to learn why the situation is as it is.

Check the libc and kernel source.

Best regards
Uwe

#1146373#48
Date:
2026-09-25 11:34:16 UTC
From:
To:
On Wed, 16 Sep 2026 20:40:58 +0200 Uwe Kleine-König <ukleinek@debian.org> wrote:
[...]

Indeed this is the expected default behaviour, not a bug.  The behaviour
can be changed through the vm.overcommit_* sysctls:
<https://docs.kernel.org/admin-guide/sysctl/vm.html#overcommit-kbytes>.

These articles may help you to make a decision whether to change the
overcommit behaviour or to set other memory limits:

- https://utcc.utoronto.ca/~cks/space/blog/linux/LinuxVMOvercommit
- https://utcc.utoronto.ca/~cks/space/blog/linux/StrictOvercommitNoLongerUsing

Ben.