summary refs log tree commit diff stats
path: root/results/classifier/zero-shot/118/debug/1876373
blob: 78c96697ee6bd0b526ac0e16da67685d2527e5c4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
debug: 0.895
permissions: 0.861
risc-v: 0.861
register: 0.851
user-level: 0.843
device: 0.842
graphic: 0.829
performance: 0.829
mistranslation: 0.824
PID: 0.821
peripherals: 0.820
ppc: 0.813
architecture: 0.805
VMM: 0.799
virtual: 0.796
arm: 0.787
semantic: 0.785
i386: 0.782
vnc: 0.774
assembly: 0.765
hypervisor: 0.752
TCG: 0.751
files: 0.747
kernel: 0.741
network: 0.726
boot: 0.710
socket: 0.677
x86: 0.657
KVM: 0.640

segfault mremap 4096

a qemu-hosted process segfaults when the program calls mremap to shrink the size of a buffer to 4096 that was allocated with mmap. See below for a C program to reproduce this issue.  I was able to compile this program for both i386 and 32-bit arm, and use qemu-i386 and qemu-arm to reproduce the segfault.  If I run the i386 program natively on my x86_64 system, no segfault occurs.  Also note that if I change the mremap size to something else such as 12288, no segfault occurs.  I also confirmed using qemu's -singlestep debug option that the segfault occurs during the mremap syscall.

If you save the source below to mremapbug.c, the following should reproduce the issue given you have gcc-multilib:

gcc -m32 mremapbug.c
# works
./a.out
# segfault
qemu-i386 a.out

If you can also compile to arm, the same thing happens when running "qemu-arm a.out".  I also tried compiling natively and running "qemu-x86_64 a.out" but no segfault in that case, not sure if it's because it is 64-bits or if it was because it was my native target.


#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>

int main(int argc, char *argv[])
{
  const size_t initial_size = 8192;

  printf("calling mmap, size=%llu\n", (unsigned long long)initial_size);
  void *mmap_ptr = mmap(NULL, initial_size,
                   PROT_READ | PROT_WRITE ,
                   MAP_PRIVATE | MAP_ANONYMOUS,
                   -1, 0);
  printf("mmap returned  : %p\n", mmap_ptr);
  if (mmap_ptr == MAP_FAILED) {
    perror("mmap");
    exit(1);
  }

  const size_t new_size = 4096;
  printf("calling mremap, size=%llu\n", (unsigned long long)new_size);
  void *remap_ptr = mremap(mmap_ptr, initial_size, new_size, 0);
  printf("mremap returned: %p\n", remap_ptr);
  if (remap_ptr != mmap_ptr) {
    perror("mreamap");
    exit(1);
  }
  printf("Success: pointers match\n");
}


This issue was found while I was pushing code that calls "mremap" to the Zig compiler repository, it's CI testing uses qemu-i386 and qemu-arm to run tests for non-native hosts.  I've filed an issue in that repository as well with details on how to reproduce this issue with the Zig compiler as well: https://github.com/ziglang/zig/issues/5245

Thanks to @LemonBoy for finding this:

It looks like this issue my be caused by this chunk of code in linux-user/mmap.c

        if (prot == 0) {
            host_addr = mremap(g2h(old_addr), old_size, new_size, flags);
            if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) {
                mmap_reserve(old_addr + old_size, new_size - old_size);
            }
        } else {
            errno = ENOMEM;
            host_addr = MAP_FAILED;
        }

if new_size is less than old_size (which is the case in my example program) then we'll get an integer underflow which would cause a very large value passed to mmap_reserve

I've submitted a patch, this is my first qemu patch so sorry if I didn't format it correctly: https://lists.gnu.org/archive/html/qemu-trivial/2020-05/msg00000.html

FYI, first patch in the previous comment was wrong.  This new patch is the correct one: https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg00183.html


Fix has been included here:
https://git.qemu.org/?p=qemu.git;a=commitdiff;h=257a7e212d5e518ac5

Patch has been included here:
https://git.qemu.org/?p=qemu.git;a=commitdiff;h=257a7e212d5e518ac53b