All of lore.kernel.org
 help / color / mirror / Atom feed
From: Uday Shankar <ushankar@purestorage.com>
To: Muchun Song <muchun.song@linux.dev>,
	Andrew Morton <akpm@linux-foundation.org>,
	Joern Engel <joern@purestorage.com>
Cc: linux-mm@kvack.org
Subject: [bug report?] unintuitive behavior when mapping over hugepage-backed PROT_NONE regions
Date: Wed, 5 Feb 2025 23:18:34 -0700	[thread overview]
Message-ID: <Z6RUOjNaBpTYUAs6@dev-ushankar.dev.purestorage.com> (raw)

I was debugging an issue with a malloc implementation when I noticed
some unintuitive behavior that happens when someone attempts to
overwrite part of a hugepage-backed PROT_NONE mapping with another
mapping. I've isolated the issue and reproduced it with the following
program:

[root@localhost ~]# cat test.c
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

#define MMAP_FLAGS_COMMON (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)

int main()
{
        size_t len = 2ULL << 30;
        void *a = mmap(
                (void *)0x7c8000000000, len, PROT_NONE,
                MMAP_FLAGS_COMMON | MAP_FIXED_NOREPLACE | MAP_NORESERVE, -1, 0);
        printf("a=%p errno %d %m\n", a, errno);
        errno = 0;

        char buf[128];
        sprintf(buf, "cp /proc/%d/smaps smaps1", getpid());
        assert(system(buf) == 0);

        len = 4096;
        void *b = mmap(
                a, len, PROT_READ | PROT_WRITE,
                MMAP_FLAGS_COMMON | MAP_POPULATE | MAP_FIXED, -1, 0);
        printf("b=%p errno %d %m\n", b, errno);
        errno = 0;

        sprintf(buf, "cp /proc/%d/smaps smaps2", getpid());
        assert(system(buf) == 0);

        return 0;
}
[root@localhost ~]# gcc -o test test.c && ./test
a=0x7c8000000000 errno 0 Success
b=0xffffffffffffffff errno 12 Cannot allocate memory
[root@localhost ~]# diff smaps1 smaps2
157,158c157,158
< 7c8000000000-7c8080000000 ---p 00000000 00:10 7332                       /anon_hugepage (deleted)
< Size:            2097152 kB
---
> 7c8000200000-7c8080000000 ---p 00200000 00:10 7332                       /anon_hugepage (deleted)
> Size:            2095104 kB

First, we map a 2G PROT_NONE region using hugepages. This succeeds. Then
we try to map a 4096-length PROT_READ | PROT_WRITE region at the
beginning of the PROT_NONE region, still using hugepages. This fails, as
expected, because 4096 is much smaller than the hugepage size configured
on the system (this is x86 with a default hugepage size of 2M). The
surprising thing is the difference in /proc/pid/smaps before and after
the failed mmap. Even though the mmap failed, the value in
/proc/pid/smaps changed, with a 2M-sized bite being taken out the front
of the mapping. This feels unintuitive to me, as I'd expect a failed
mmap to have no effect on the virtual memory mappings of the calling
process whatsoever.

I initially saw this on an ancient redhat kernel, but I was able to
reproduce it on 6.13 as well. So I assume this behavior still exists and
has been around forever.


             reply	other threads:[~2025-02-06  6:18 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-06  6:18 Uday Shankar [this message]
2025-02-06  9:01 ` [bug report?] unintuitive behavior when mapping over hugepage-backed PROT_NONE regions Oscar Salvador
2025-02-06 18:11   ` Jörn Engel
2025-02-06 18:54     ` Oscar Salvador
2025-02-07 10:29       ` Lorenzo Stoakes
2025-02-07 10:49     ` Vlastimil Babka
2025-02-07 12:33     ` Lorenzo Stoakes
2025-02-06 19:44   ` Uday Shankar
2025-02-07 13:12 ` Lorenzo Stoakes
2025-02-07 19:35   ` Jörn Engel
2025-02-08 16:02     ` Lorenzo Stoakes
2025-02-08 17:37       ` Jörn Engel
2025-02-08 17:40         ` Lorenzo Stoakes
2025-02-08 17:53           ` Jörn Engel
2025-02-08 18:00             ` Lorenzo Stoakes
2025-02-08 21:16               ` Jörn Engel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Z6RUOjNaBpTYUAs6@dev-ushankar.dev.purestorage.com \
    --to=ushankar@purestorage.com \
    --cc=akpm@linux-foundation.org \
    --cc=joern@purestorage.com \
    --cc=linux-mm@kvack.org \
    --cc=muchun.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.