1 /* BZ #18877 and #21270 mmap offset test.
3 Copyright (C) 2015-2017 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
28 #include <support/check.h>
31 static long int page_shift
;
32 static char fname
[] = "tst-mmap-offset-XXXXXX";
35 do_prepare (int argc
, char **argv
)
37 fd
= mkstemp64 (fname
);
39 FAIL_EXIT1 ("mkstemp failed");
42 FAIL_EXIT1 ("unlink failed");
44 long sz
= sysconf(_SC_PAGESIZE
);
47 page_shift
= ffs (sz
) - 1;
50 #define PREPARE do_prepare
53 /* Check if negative offsets are handled correctly by mmap. */
55 do_test_bz18877 (void)
57 const int prot
= PROT_READ
| PROT_WRITE
;
58 const int flags
= MAP_SHARED
;
59 const unsigned long length
= 0x10000;
60 const unsigned long offset
= 0xace00000;
61 const unsigned long size
= offset
+ length
;
64 if (ftruncate64 (fd
, size
))
65 FAIL_RET ("ftruncate64 failed");
67 addr
= mmap (NULL
, length
, prot
, flags
, fd
, offset
);
68 if (MAP_FAILED
== addr
)
69 FAIL_RET ("mmap failed");
71 /* This memcpy is likely to SIGBUS if mmap has messed up with offset. */
72 memcpy (addr
, fname
, sizeof (fname
));
77 /* Check if invalid offset are handled correctly by mmap. */
79 do_test_bz21270 (void)
81 /* For architectures with sizeof (off_t) < sizeof (off64_t) mmap is
82 implemented with __SYS_mmap2 syscall and the offset is represented in
83 multiples of page size. For offset larger than
84 '1 << (page_shift + 8 * sizeof (off_t))' (that is, 1<<44 on system with
85 page size of 4096 bytes) the system call silently truncates the offset.
86 For this case glibc mmap implementation returns EINVAL. */
87 const int prot
= PROT_READ
| PROT_WRITE
;
88 const int flags
= MAP_SHARED
;
89 const int64_t offset
= 1ULL << (page_shift
+ 8 * sizeof (uint32_t));
90 const size_t length
= 4096;
92 void *addr
= mmap64 (NULL
, length
, prot
, flags
, fd
, offset
);
93 if (sizeof (off_t
) < sizeof (off64_t
))
95 if ((addr
!= MAP_FAILED
) && (errno
!= EINVAL
))
96 FAIL_RET ("mmap succeed");
100 if (addr
== MAP_FAILED
)
101 FAIL_RET ("mmap failed");
112 ret
+= do_test_bz18877 ();
113 ret
+= do_test_bz21270 ();
118 #include <support/test-driver.c>