All of lore.kernel.org
 help / color / mirror / Atom feed
* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
@ 2017-03-24 14:21 Pratyush Anand
  2017-03-24 16:15 ` Mark Rutland
  0 siblings, 1 reply; 10+ messages in thread
From: Pratyush Anand @ 2017-03-24 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi All,

One of the hugetlbfs test[1] fails on ARM64 kernel with Segmentation 
fault. Segmentation fault (unhandled level 2 translation fault [3]) 
happens just after kernel returns to user space from mmap() system call. 
See the tailored version of failing test case [2] (it reproduces in 
maximum 10 trials).

When it fails lr shows the address of the instruction which follow 
mmap() call in main. Also, if test is run with strace, then it says that 
mmap() system call was fine. (so,I believe lr is correct). Cross checked 
from /proc/pid/maps and PC is also correct.It is the address of 
instruction where kernel will return after executing mmap() system call. 
So, when the first user space instruction is executed after returning 
from kernel, it gives segmentation fault. Not sure what went wrong..Just 
a guess, probably this page was swapped out (core dump does not have 
this page), but kernel expect it to be there. Any pointer to debug will 
be helpful.

Following is one failing scenario, which leads to above assertions.

 From /proc/pid/maps:
ffffa1760000-ffffa18c0000 r-xp 00000000 fd:00 33718606 
/usr/lib64/libc-2.17.so

from dmesg:
[34928.473302] PC is at 0xffffa1835a44
[34928.476771] LR is at 0x400a3c

offset of failing address in libc-2.17.so =   0xffffa1835a44 - 
0xffffa1760000 = 0xD5A44

from objdump of  libc-2.17.so:
00000000000d5a30 <mmap>:
    d5a30:       93407c42        sxtw    x2, w2
    d5a34:       93407c63        sxtw    x3, w3
    d5a38:       93407c84        sxtw    x4, w4
    d5a3c:       d2801bc8        mov     x8, #0xde 
// #222
    d5a40:       d4000001        svc     #0x0
    d5a44:       b140041f        cmn     x0, #0x1, lsl #12
    d5a48:       54000048        b.hi    d5a50 <mmap+0x20>

and from objdump of test (hugetlb_test_stack):
00000000004008dc <main>:
   [...]
   400a30:       b940f7a4        ldr     w4, [x29,#244]
   400a34:       d2800005        mov     x5, #0x0 
// #0
   400a38:       97ffff3e        bl      400730 <mmap@plt>
   400a3c:       f9006fa0        str     x0, [x29,#216]

from core dump:
Program terminated with signal 11, Segmentation fault.
#0  0x0000ffffa1835a44 in ?? ()

(gdb) x/g 0x0000ffffa1835a44
0xffffa1835a44: Cannot access memory at address 0xffffa1835a44

~Pratyush


[1] 
https://github.com/libhugetlbfs/libhugetlbfs/blob/master/tests/stack_grow_into_huge.c

[2]
---------------------------------------------------------------------------
# cat hugetlb_test_stack.c

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>

#define ALIGN(x, a)     (((x) + (a) - 1) & ~((a) - 1))
#define PALIGN(p, a)    ((void *)ALIGN((unsigned long)(p), (a)))

int main(int argc, char *argv[])
{
         long hpage_size;;
         void *stack_address, *mmap_address, *mmap_ret_address;
         struct rlimit r;
         int fd;

         if (argc < 3) {
                 printf("Pass hugetlb page size as 1st argument and
path of a file in hugetlbfs as second argument\n");
                 exit(0);
         }
         hpage_size = atol(argv[1]);

         printf("hpage_size is %lx\n", hpage_size);
         printf("file path is %s\n", argv[2]);
         r.rlim_cur = RLIM_INFINITY;
         r.rlim_max = RLIM_INFINITY;
         setrlimit(RLIMIT_STACK, &r);

         fd = open(argv[2], O_RDWR);

         if (fd < 0) {
                 printf("open() failed: %s\n", strerror(errno));
                 return -1;
         }

         stack_address = alloca(0);
         mmap_address = PALIGN(stack_address - 2 * hpage_size, hpage_size);

         printf("Address to be mapped is %p\n", mmap_address);
         mmap_ret_address = mmap(mmap_address, hpage_size, 
PROT_READ|PROT_WRITE,
                                 MAP_FIXED|MAP_SHARED, fd, 0);
         printf("mmap_ret_address is %p\n", mmap_ret_address);
}

# gcc -o hugetlb_test_stack hugetlb_test_stack.c
# ls /sys/kernel/mm/hugepages/
hugepages-2048kB  hugepages-524288kB

I used 524288KB page size file for test. It did not reproduces with 
2048K page size.

# echo 5 > /sys/kernel/mm/hugepages/hugepages-524288kB/nr_hugepages
#  mount -t hugetlbfs none /mnt/hugetlbfs -o pagesize=524288K
# touch /mnt/hugetlbfs/test
# ./hugetlb_test_stack 536870912  /mnt/hugetlbfs/test
---------------------------------------------------------------------------

[3]
[34928.425865] hugetlb_test_st[10566]: unhandled level 2 translation 
fault (11) at 0xffffa1835a44, esr 0x82000006
[34928.435848] pgd = ffff8003c89eec00
[34928.439231] [ffffa1835a44] *pgd=00000043cfc70003, 
*pud=00000043cfc70003, *pmd=0000000000000000
[34928.447818]
[34928.449303] CPU: 1 PID: 10566 Comm: hugetlb_test_st Not tainted 
4.10.0-XXXXXX.aarch64 #1
[34928.457706] Hardware name: AppliedMicro X-Gene Mustang Board/X-Gene 
Mustang Board, BIOS 3.06.25 Oct 17 2016
[34928.467405] task: ffff8003c89b8000 task.stack: ffff800370294000
[34928.473302] PC is at 0xffffa1835a44
[34928.476771] LR is at 0x400a3c
[34928.479721] pc : [<0000ffffa1835a44>] lr : [<0000000000400a3c>] 
pstate: 80000000
[34928.487095] sp : 0000ffffc7384fd0
[34928.490400] x29: 0000ffffc7384fd0 x28: 0000000000000000
[34928.495685] x27: 0000000000000000 x26: 0000000000000000
[34928.500980] x25: 0000000000000000 x24: 0000000000000000
[34928.506265] x23: 0000000000000000 x22: 0000000000000000
[34928.511557] x21: 0000000000400770 x20: 0000000000000000
[34928.516841] x19: 0000000000000000 x18: 0000ffffc7384da0
[34928.522130] x17: 0000000000420048 x16: 0000ffffa1835a30
[34928.527414] x15: 00000000001815e7 x14: 0000ffffa194ffb8
[34928.532702] x13: ffffffffffffffff x12: 0000000000000013
[34928.537986] x11: 0000ffffc738f6de x10: 00000000ffffffff
[34928.543276] x9 : 0000000000400bd9 x8 : 00000000000000de
[34928.548559] x7 : 0000000000000000 x6 : 0000000000000000
[34928.553848] x5 : 0000000000000000 x4 : 0000000000000003
[34928.559131] x3 : 0000000000000011 x2 : 0000000000000003
[34928.564431] x1 : 0000000020000000 x0 : 0000ffffa0000000
[34928.569718]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
  2017-03-24 14:21 Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area Pratyush Anand
@ 2017-03-24 16:15 ` Mark Rutland
  2017-03-24 16:41   ` Pratyush Anand
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2017-03-24 16:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Fri, Mar 24, 2017 at 07:51:34PM +0530, Pratyush Anand wrote:
> # cat hugetlb_test_stack.c
> 
> #include <errno.h>
> #include <fcntl.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/mman.h>
> #include <sys/resource.h>
> #include <sys/stat.h>
> #include <sys/time.h>
> #include <sys/types.h>
> 
> #define ALIGN(x, a)     (((x) + (a) - 1) & ~((a) - 1))
> #define PALIGN(p, a)    ((void *)ALIGN((unsigned long)(p), (a)))
> 
> int main(int argc, char *argv[])
> {
>         long hpage_size;;
>         void *stack_address, *mmap_address, *mmap_ret_address;
>         struct rlimit r;
>         int fd;
> 
>         if (argc < 3) {
>                 printf("Pass hugetlb page size as 1st argument and
> path of a file in hugetlbfs as second argument\n");
>                 exit(0);
>         }
>         hpage_size = atol(argv[1]);
> 
>         printf("hpage_size is %lx\n", hpage_size);
>         printf("file path is %s\n", argv[2]);
>         r.rlim_cur = RLIM_INFINITY;
>         r.rlim_max = RLIM_INFINITY;
>         setrlimit(RLIMIT_STACK, &r);
> 
>         fd = open(argv[2], O_RDWR);
> 
>         if (fd < 0) {
>                 printf("open() failed: %s\n", strerror(errno));
>                 return -1;
>         }
> 
>         stack_address = alloca(0);
>         mmap_address = PALIGN(stack_address - 2 * hpage_size, hpage_size);
> 
>         printf("Address to be mapped is %p\n", mmap_address);
>         mmap_ret_address = mmap(mmap_address, hpage_size,
> PROT_READ|PROT_WRITE,
>                                 MAP_FIXED|MAP_SHARED, fd, 0);
>         printf("mmap_ret_address is %p\n", mmap_ret_address);
> }
> 
> # gcc -o hugetlb_test_stack hugetlb_test_stack.c
> # ls /sys/kernel/mm/hugepages/
> hugepages-2048kB  hugepages-524288kB
> 
> I used 524288KB page size file for test. It did not reproduces with
> 2048K page size.
> 
> # echo 5 > /sys/kernel/mm/hugepages/hugepages-524288kB/nr_hugepages
> #  mount -t hugetlbfs none /mnt/hugetlbfs -o pagesize=524288K
> # touch /mnt/hugetlbfs/test
> # ./hugetlb_test_stack 536870912  /mnt/hugetlbfs/test

I modified the test to print out some additional information, and ran it under
GDB, with a breakpoint on main, and ASLR enabled with:

	set disable-randomization off

It's clear from the log that the test is simply blatting a number of
important mappings including libc, so I think this is simply a broken
test.

(gdb) run               
Starting program: /host/home/nanook/htfs 536870912 /mnt/hugetlbfs/test

Breakpoint 1, 0x0000000000400848 in main ()
(gdb) info proc mappings
process 1301
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
            0x400000           0x410000    0x10000        0x0 /host/home/nanook/htfs
            0x410000           0x420000    0x10000        0x0 /host/home/nanook/htfs
      0xffffa76f0000     0xffffa7700000    0x10000        0x0 
      0xffffa7700000     0xffffa7830000   0x130000        0x0 /host/lib/aarch64-linux-gnu/libc-2.19.so
      0xffffa7830000     0xffffa7840000    0x10000   0x130000 /host/lib/aarch64-linux-gnu/libc-2.19.so
      0xffffa7840000     0xffffa7850000    0x10000        0x0 [vvar]
      0xffffa7850000     0xffffa7860000    0x10000        0x0 [vdso]
      0xffffa7860000     0xffffa7880000    0x20000        0x0 /host/lib/aarch64-linux-gnu/ld-2.19.so
      0xffffa7880000     0xffffa7890000    0x10000    0x10000 /host/lib/aarch64-linux-gnu/ld-2.19.so
      0xffffd90f0000     0xffffd9120000    0x30000        0x0 [stack]
(gdb) continue          
Continuing.
hpage_size is 20000000
file path is /mnt/hugetlbfs/test
Range to be mapped is 0xffffa0000000-0xffffbfffffff
Currently main at 0x400840

Program received signal SIGILL, Illegal instruction.
0x0000ffffa77c4c04 in __mmap (addr=<optimized out>, len=536870912, prot=3, 
    flags=17, fd=3, offset=0)
    at ../ports/sysdeps/unix/sysv/linux/aarch64/mmap.c:29
29      ../ports/sysdeps/unix/sysv/linux/aarch64/mmap.c: No such file or directory.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
  2017-03-24 16:15 ` Mark Rutland
@ 2017-03-24 16:41   ` Pratyush Anand
  2017-03-24 17:25     ` Mark Rutland
  0 siblings, 1 reply; 10+ messages in thread
From: Pratyush Anand @ 2017-03-24 16:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

On Friday 24 March 2017 09:45 PM, Mark Rutland wrote:
> It's clear from the log that the test is simply blatting a number of
> important mappings including libc, so I think this is simply a broken
> test.

Thanks a lot for taking out time and investigating it so quickly. Yes, I 
noticed that as well. Frankly, I do not understand that why that 
upstream libhugetlbfs test is like that. But that test has been passing 
on different architecture for quite long time.

Moreover, even if mmap() in test routine crosses over many other 
text/rd/rw area mappings, should it fail? We are not writing anything to 
mmaped area. So, why should just a creation of another map result in 
segmentation fault?

~Pratyush

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
  2017-03-24 16:41   ` Pratyush Anand
@ 2017-03-24 17:25     ` Mark Rutland
  2017-03-24 18:02       ` Pratyush Anand
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2017-03-24 17:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 24, 2017 at 10:11:10PM +0530, Pratyush Anand wrote:
> Hi Mark,
> 
> On Friday 24 March 2017 09:45 PM, Mark Rutland wrote:
> >It's clear from the log that the test is simply blatting a number of
> >important mappings including libc, so I think this is simply a broken
> >test.
> 
> Thanks a lot for taking out time and investigating it so quickly.
> Yes, I noticed that as well. Frankly, I do not understand that why
> that upstream libhugetlbfs test is like that. But that test has been
> passing on different architecture for quite long time.

I guess that on other architectures, the test is run with a smaller
hugepage size, which happens to not clobber impoertant data.

> Moreover, even if mmap() in test routine crosses over many other
> text/rd/rw area mappings, should it fail? We are not writing
> anything to mmaped area. So, why should just a creation of another
> map result in segmentation fault?

The new mapping replaces the old mappings that it clobbers, so all the
old data/code is gone. Loads or instruction fetches will see data from
the new mapping.

In my case, since the libc code was clobbered, the CPU tried to execute
the zeroes it was clobbered with, and took an illegal instruction abort.

For your report, it's not clear to me what's going on. Did you take the
/proc/pid/maps data from teh exact same process that the segfault
occurred in? and/or did you disable ASLR?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
  2017-03-24 17:25     ` Mark Rutland
@ 2017-03-24 18:02       ` Pratyush Anand
  2017-03-24 18:16         ` Mark Rutland
  0 siblings, 1 reply; 10+ messages in thread
From: Pratyush Anand @ 2017-03-24 18:02 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 24 March 2017 10:55 PM, Mark Rutland wrote:
>> Moreover, even if mmap() in test routine crosses over many other
>> text/rd/rw area mappings, should it fail? We are not writing
>> anything to mmaped area. So, why should just a creation of another
>> map result in segmentation fault?
> The new mapping replaces the old mappings that it clobbers, so all the
> old data/code is gone. Loads or instruction fetches will see data from
> the new mapping.
>

Humm..I see..But in that case mmap() should have failed and return 
MAP_FAILED instead of remapping and which could cause a segfault.
I see that upstream test case, has mmap() in a loop and it goes further 
only with a successful mapping. So, if it would have failed then 
probably test would have tried next address for mmaping until it would 
have touched heap area.

> In my case, since the libc code was clobbered, the CPU tried to execute
> the zeroes it was clobbered with, and took an illegal instruction abort.
>
> For your report, it's not clear to me what's going on. Did you take the
> /proc/pid/maps data from teh exact same process that the segfault
> occurred in? and/or did you disable ASLR?

Yes, it is from the same process. Since, I was not able to reproduce 
with gdb so, I had inserted a scanf() just before mmap() and then had 
read /proc/pid/maps.

~Pratyush

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
  2017-03-24 18:02       ` Pratyush Anand
@ 2017-03-24 18:16         ` Mark Rutland
  2017-03-25 12:14           ` Pratyush Anand
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2017-03-24 18:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 24, 2017 at 11:32:58PM +0530, Pratyush Anand wrote:
> 
> 
> On Friday 24 March 2017 10:55 PM, Mark Rutland wrote:
> >>Moreover, even if mmap() in test routine crosses over many other
> >>text/rd/rw area mappings, should it fail? We are not writing
> >>anything to mmaped area. So, why should just a creation of another
> >>map result in segmentation fault?
> >The new mapping replaces the old mappings that it clobbers, so all the
> >old data/code is gone. Loads or instruction fetches will see data from
> >the new mapping.
> 
> Humm..I see..But in that case mmap() should have failed and return
> MAP_FAILED instead of remapping and which could cause a segfault.

That does nto appear to be the case. As per the mmap man page:

  MAP_FIXED
      Don't  interpret addr as a hint: place the mapping at exactly that
      address.  addr must be a multiple of the page size.  If the memory
      region specified by addr and len overlaps pages of any existing
      mapping(s), then the overlapped part of the existing mapping(s)
      will  be discarded.  If the specified address cannot be used,
      mmap() will fail.  Because requiring a fixed address for a mapping
      is less portable, the use of this option is discouraged.

[...]

> >For your report, it's not clear to me what's going on. Did you take the
> >/proc/pid/maps data from teh exact same process that the segfault
> >occurred in? and/or did you disable ASLR?
> 
> Yes, it is from the same process.

That is troubling; I cannot explain that.

> Since, I was not able to reproduce with gdb so, I had inserted a
> scanf() just before mmap() and then had read /proc/pid/maps.

That might be because GDB disables ASLR by default. Did you re-enable
ASLR within GDB with:

	set disable-randomization off

If not, could you give that a go?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
  2017-03-24 18:16         ` Mark Rutland
@ 2017-03-25 12:14           ` Pratyush Anand
  2017-03-27 12:18             ` Mark Rutland
  0 siblings, 1 reply; 10+ messages in thread
From: Pratyush Anand @ 2017-03-25 12:14 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 24 March 2017 11:46 PM, Mark Rutland wrote:
>>> For your report, it's not clear to me what's going on. Did you take the
>>> /proc/pid/maps data from teh exact same process that the segfault
>>> occurred in? and/or did you disable ASLR?
>> Yes, it is from the same process.
> That is troubling; I cannot explain that.

Can you pl try in an infinite loop for some time and see if "SIGSEGV" is 
received in any of the run at your end.

# while [[ 1 ]]; do  ./hugetlb_test_stack 536870912 
/mnt/hugetlbfs/test;done

>
>> Since, I was not able to reproduce with gdb so, I had inserted a
>> scanf() just before mmap() and then had read /proc/pid/maps.
> That might be because GDB disables ASLR by default. Did you re-enable
> ASLR within GDB with:
>
> 	set disable-randomization off
>
> If not, could you give that a go?

Yes, with ASLR enabled, it reproduced in GDB as well. I do not see 
SIGILL, it is SIGSEGV there too.

(gdb) set disable-randomization off
(gdb) b main
Breakpoint 1 at 0x400884
(gdb) r
Starting program: /home/panand/work/hugetlb/./hugetlb_test_stack 
536870912 /mnt/hugetlbfs/test

Breakpoint 1, 0x0000000000400884 in main ()
(gdb) info proc mappings
process 2949
Mapped address spaces:

           Start Addr           End Addr       Size     Offset objfile
             0x400000           0x410000    0x10000        0x0 
/home/panand/work/hugetlb/hugetlb_test_stack
             0x410000           0x420000    0x10000        0x0 
/home/panand/work/hugetlb/hugetlb_test_stack
             0x420000           0x430000    0x10000    0x10000 
/home/panand/work/hugetlb/hugetlb_test_stack
       0xffffada70000     0xffffadbd0000   0x160000        0x0 
/usr/lib64/libc-2.17.so
       0xffffadbd0000     0xffffadbe0000    0x10000   0x150000 
/usr/lib64/libc-2.17.so
       0xffffadbe0000     0xffffadbf0000    0x10000   0x160000 
/usr/lib64/libc-2.17.so
       0xffffadc10000     0xffffadc20000    0x10000        0x0 [vvar]
       0xffffadc20000     0xffffadc30000    0x10000        0x0 [vdso]
       0xffffadc30000     0xffffadc50000    0x20000        0x0 
/usr/lib64/ld-2.17.so
       0xffffadc50000     0xffffadc60000    0x10000    0x10000 
/usr/lib64/ld-2.17.so
       0xffffadc60000     0xffffadc70000    0x10000    0x20000 
/usr/lib64/ld-2.17.so
       0xffffcb1d0000     0xffffcb200000    0x30000        0x0 [stack]
(gdb) c
Continuing.
hpage_size is 20000000
file path is /mnt/hugetlbfs/test
stack_address is 0xffffcb1facc0
Address to be mapped is 0xffffa0000000

Program received signal SIGSEGV, Segmentation fault.
0x0000ffffadb45a44 in __mmap (addr=<optimized out>, len=536870912, 
prot=3, flags=17, fd=7, offset=0)
     at ../ports/sysdeps/unix/sysv/linux/aarch64/mmap.c:29
29        return (__ptr_t) INLINE_SYSCALL (mmap, 6, addr, len, prot, 
flags, fd, offset);
(gdb)

~Pratyush

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
  2017-03-25 12:14           ` Pratyush Anand
@ 2017-03-27 12:18             ` Mark Rutland
  2017-03-27 13:20               ` Pratyush Anand
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2017-03-27 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Mar 25, 2017 at 05:44:58PM +0530, Pratyush Anand wrote:
> On Friday 24 March 2017 11:46 PM, Mark Rutland wrote:
> >>>For your report, it's not clear to me what's going on. Did you take the
> >>>/proc/pid/maps data from teh exact same process that the segfault
> >>>occurred in? and/or did you disable ASLR?
> >>Yes, it is from the same process.
> >That is troubling; I cannot explain that.
> 
> Can you pl try in an infinite loop for some time and see if
> "SIGSEGV" is received in any of the run at your end.

After several thousand runs, I see a few unhandled translations faults
(all for address 0) in dmesg. 

I suspect that in this case, the hugepage has clobbered some
datastructure used shortly after the return from the syscall, and we end
up dereferencing a pointer that's been replaced with zeroes.

> >>Since, I was not able to reproduce with gdb so, I had inserted a
> >>scanf() just before mmap() and then had read /proc/pid/maps.
> >That might be because GDB disables ASLR by default. Did you re-enable
> >ASLR within GDB with:
> >
> >	set disable-randomization off
> >
> >If not, could you give that a go?
> 
> Yes, with ASLR enabled, it reproduced in GDB as well. I do not see
> SIGILL, it is SIGSEGV there too.

So far, I have not managed to trigger a single SIGSEGV while running
under GDB.

However, I have a theory that could explain that. I suspect that my
toolchain has built the binary with an executable stack, while yours has
not. Linux automatically sets READ_IMPLIES_EXEC for binaries with
executable stacks, which IIUC would implicitly make the mmap RWX rather
than RW.

So in my case, the huge page is executable, and I get a SIGILL when
trying to execute from it. In your case, the huge page is not
executable, so you get a SIGSEGV.

Looking at your report below:

> Mapped address spaces:
> 
>           Start Addr           End Addr       Size     Offset objfile
>             0x400000           0x410000    0x10000        0x0
> /home/panand/work/hugetlb/hugetlb_test_stack
>             0x410000           0x420000    0x10000        0x0
> /home/panand/work/hugetlb/hugetlb_test_stack
>             0x420000           0x430000    0x10000    0x10000
> /home/panand/work/hugetlb/hugetlb_test_stack

All the entries from here ...

>       0xffffada70000     0xffffadbd0000   0x160000        0x0
> /usr/lib64/libc-2.17.so
>       0xffffadbd0000     0xffffadbe0000    0x10000   0x150000
> /usr/lib64/libc-2.17.so
>       0xffffadbe0000     0xffffadbf0000    0x10000   0x160000
> /usr/lib64/libc-2.17.so
>       0xffffadc10000     0xffffadc20000    0x10000        0x0 [vvar]
>       0xffffadc20000     0xffffadc30000    0x10000        0x0 [vdso]
>       0xffffadc30000     0xffffadc50000    0x20000        0x0
> /usr/lib64/ld-2.17.so
>       0xffffadc50000     0xffffadc60000    0x10000    0x10000
> /usr/lib64/ld-2.17.so
>       0xffffadc60000     0xffffadc70000    0x10000    0x20000

... to here ...

> /usr/lib64/ld-2.17.so
>       0xffffcb1d0000     0xffffcb200000    0x30000        0x0 [stack]
> (gdb) c
> Continuing.
> hpage_size is 20000000
> file path is /mnt/hugetlbfs/test
> stack_address is 0xffffcb1facc0
> Address to be mapped is 0xffffa0000000

... are clobbered by this map, which will cover the range:
	
	0xffffa0000000-0xFFFFC0000000

> Program received signal SIGSEGV, Segmentation fault.
> 0x0000ffffadb45a44 in __mmap (addr=<optimized out>, len=536870912,
> prot=3, flags=17, fd=7, offset=0)

That address falls within libc-2.17.so, which is clobbered by the mmap.

Do you happen to know how to parse that 'prot=3' in the SEGV report? I'm
guessing that means RW, !X.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
  2017-03-27 12:18             ` Mark Rutland
@ 2017-03-27 13:20               ` Pratyush Anand
  2017-03-27 17:45                 ` Mark Rutland
  0 siblings, 1 reply; 10+ messages in thread
From: Pratyush Anand @ 2017-03-27 13:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

Thanks a lot for your explanations!!

On Monday 27 March 2017 05:48 PM, Mark Rutland wrote:
> So far, I have not managed to trigger a single SIGSEGV while running
> under GDB.
>
> However, I have a theory that could explain that. I suspect that my
> toolchain has built the binary with an executable stack, while yours has
> not. Linux automatically sets READ_IMPLIES_EXEC for binaries with
> executable stacks, which IIUC would implicitly make the mmap RWX rather
> than RW.
>
> So in my case, the huge page is executable, and I get a SIGILL when
> trying to execute from it. In your case, the huge page is not
> executable, so you get a SIGSEGV.

Yes, your theory seems  convincing.
I passed PROT_EXEC as well along with PROT_READ|PROT_WRITE to mmap(),and 
then I received SIGILL.

[...]

>> Program received signal SIGSEGV, Segmentation fault.
>> 0x0000ffffadb45a44 in __mmap (addr=<optimized out>, len=536870912,
>> prot=3, flags=17, fd=7, offset=0)
> That address falls within libc-2.17.so, which is clobbered by the mmap.
>
> Do you happen to know how to parse that 'prot=3' in the SEGV report? I'm
> guessing that means RW, !X.

Yes, it seems like that.

https://sourceware.org/git/?p=glibc.git;a=blob;f=bits/mman-linux.h;h=8126ce836947718576f09cd8f874a25b2c1340f7;hb=HEAD

~Pratyush

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area
  2017-03-27 13:20               ` Pratyush Anand
@ 2017-03-27 17:45                 ` Mark Rutland
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Rutland @ 2017-03-27 17:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 27, 2017 at 06:50:53PM +0530, Pratyush Anand wrote:
> Hi Mark,
> 
> Thanks a lot for your explanations!!
> 
> On Monday 27 March 2017 05:48 PM, Mark Rutland wrote:
> >So far, I have not managed to trigger a single SIGSEGV while running
> >under GDB.
> >
> >However, I have a theory that could explain that. I suspect that my
> >toolchain has built the binary with an executable stack, while yours has
> >not. Linux automatically sets READ_IMPLIES_EXEC for binaries with
> >executable stacks, which IIUC would implicitly make the mmap RWX rather
> >than RW.
> >
> >So in my case, the huge page is executable, and I get a SIGILL when
> >trying to execute from it. In your case, the huge page is not
> >executable, so you get a SIGSEGV.
> 
> Yes, your theory seems  convincing.
> I passed PROT_EXEC as well along with PROT_READ|PROT_WRITE to
> mmap(),and then I received SIGILL.

Ok, I think that explains it, then.

I was a little confused by the PMD being NULL in your initial splat, but
from a look at the mmap() codepaths, we lazily fault in hugetlbfs
mappings unless explicitly asked to populate them.

So mmap would have cleared any existing mappings (leaving the PMD NULL), 
set up the VMA as RW, then returned without setting up the new mapping
inthe page tables. Since that clobbered libc, when we get back to
userspace we immediately take an instruction abort, and since we're not
supposed to have execute permission, we get a SEGV.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-03-27 17:45 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-24 14:21 Query: ARM64: A random failure with hugetlbfs linked mmap() of a stack area Pratyush Anand
2017-03-24 16:15 ` Mark Rutland
2017-03-24 16:41   ` Pratyush Anand
2017-03-24 17:25     ` Mark Rutland
2017-03-24 18:02       ` Pratyush Anand
2017-03-24 18:16         ` Mark Rutland
2017-03-25 12:14           ` Pratyush Anand
2017-03-27 12:18             ` Mark Rutland
2017-03-27 13:20               ` Pratyush Anand
2017-03-27 17:45                 ` Mark Rutland

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.