[libc-commits] [libc] [libc][mmap] implement mmap in terms of mmap2 for 32b targets (PR #96700)
via libc-commits
libc-commits at lists.llvm.org
Tue Jun 25 14:41:11 PDT 2024
================
@@ -8,56 +8,91 @@
#include "src/sys/mman/mmap.h"
+#include "config/linux/app.h" // app
+#include "hdr/sys_auxv_macros.h" // AT_PAGESZ
+#include "hdr/sys_mman_macros.h" // MAP_FAILED
+#include "hdr/types/off64_t.h"
+#include "hdr/types/off_t.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/block.h" // align_up
#include "src/__support/common.h"
-
#include "src/errno/libc_errno.h"
-#include <linux/param.h> // For EXEC_PAGESIZE.
+#include "src/sys/auxv/getauxval.h"
+
+#include <stddef.h> // size_t
+#include <stdint.h> // PTRDIFF_MAX
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE {
+// Older 32b systems generally have a SYS_mmap2 that accepts a 32b value which
+// was a 64b value shifted down by 12; this magic constant isn't exposed via
+// UAPI headers, but its in kernel sources for mmap2 implementations.
+#ifdef SYS_mmap2
+
+// TODO: move these helpers to OSUtil?
+#ifdef LIBC_FULL_BUILD
+unsigned long get_page_size() { return app.page_size; }
+#else
+unsigned long get_page_size() {
+ // TODO: is it ok for mmap to call getauxval in overlay mode? Or is there a
+ // risk of infinite recursion?
+ return ::getauxval(AT_PAGESZ);
+}
+#endif // LIBC_FULL_BUILD
+
+void *mmap64(void *addr, size_t size, int prot, int flags, int fd,
+ off64_t offset) {
+ constexpr size_t MMAP2_SHIFT = 12;
+
+ if (offset < 0 || offset % (1UL << MMAP2_SHIFT)) {
+ libc_errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ // Prevent allocations large enough for `end - start` to overflow,
+ // to avoid security bugs.
+ size_t rounded = align_up(size, get_page_size());
+ if (rounded < size || rounded > PTRDIFF_MAX) {
+ libc_errno = ENOMEM;
+ return MAP_FAILED;
+ }
----------------
enh-google wrote:
for LP64, you don't need any of this. (that's why you couldn't find bionic's LP64 code --- it's a trivial generated assembler stub.)
for ILP32 ... these are the checks you'll have to do yourself, because these are the checks that tell you whether your translation to mmap2(2) is valid or not.
given that you've got everything in the same file, `#if __LP64__` might be clearer than the `SYS_mmap2` check, which to the inexperienced eye might look like mmap2 is the new version of mmap, like faccessat2 or whatever.
https://github.com/llvm/llvm-project/pull/96700
More information about the libc-commits
mailing list