ULIMIT: limiting user virtual address space (stack inluded)

Valdis Kl=?utf-8?Q?=c4=93?=tnieks valdis.kletnieks at vt.edu
Thu May 2 11:50:47 EDT 2019

On Thu, 02 May 2019 09:06:09 -0400, Karaoui mohamed lamine said:

> According to the man page of "ulimit", it is possible to limit the virtual
> address space of a user process: https://ss64.com/bash/ulimit.html
> To limit the virtual address space to 2 GB:
> $ ulimit -SH -v 1048576

It's possible.  It also probably doesn't do what you think it does. In particular,
you may be looking for the -d (data) and/or -m (memory) flags.

Also, to limit it to 2G, you're going to need 'ulimit -v 2097152'

> However, it seems that "stack" allocation ignores this limit (I tried with
> both kernel 4.4 and 4.15).

I'm going to go out on a limb and say that what you think is happening
is not in fact what is happening.

> I found this article (patch) that seems to fix the problem:
> https://lwn.net/Articles/373701/

It's unclear what your actual problem is, but given that the patch
has been in the kernel for a decade, it's almost certainly not related.

> My questions are:
> - Why is the stack allocation not placed within the "ulimit" limit? (is it
> a bug?)

Rule of thumb:  Before asking why something happens, verify that it does
in fact happen.

Consider the following C program:

[~] cat > moby-stack.c
#include <unistd.h>

#define MOBYSTACK 16384
#define BIG 2048

int recurse(int level) {
double a[BIG]; /* chew up stack space */

if (level == MOBYSTACK) sleep(9999999);

int main() {recurse(0); };
[~] gcc moby-stack.c
[~] ulimit -v 16384
[~] ulimit -s 32768
[~] ./a.out
Segmentation fault (core dumped)

Examination of the core file shows it created 895 stack entries, for a total of
895 * 8 * 2048 or 14,663,680 or so bytes of stack. That's about what you'd
expect given a virtual limit of 16M, and a bit of space taken up by shared
libraries and so on. Re-running with a virtual limit of 32768 lets it get 1916
stack entries deep. Again, that's about where you'd expect the explosion to
happen with that virtual limit in place. So regardless of the stack limit, it
blows up when it gets to the -v limit.

Conclusion: The stack *is* included in the -v virtual limit.

> - Is there a way, in user space, to force the stack to be allocated at a
> certain address?

Sure.  mmap() yourself a chunk of anonymous pages at the address you want,
and call a little assembler stub that sets your registers.  You'll probably have
to ensure you allocate enough pages, or handle expanding onto new pages
yourself (including making sure there's free pages to grow into).  And of course,
you're basically stuck with that stack, returning to older functions on the old
stack is going to be *really* hard.  So you'll probably want to do that in main().

Google for 'linux green threads' for the gory details.  Java used them on Linux until 2017
or so.

> - Will the patch above (or similar) ever be integrated into the Linux
> kernel?

See above.  It's been in the kernel for a decade.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20190502/70a79d24/attachment.sig>

More information about the Kernelnewbies mailing list