/* * kasan_map_memory - maps memory from @start with a size of @len. * The allocated memory is filled with zeroes upon success. * @start: the start address of the memory to be mapped * @len: the length of the memory to be mapped * * This function is used to map shadow memory for KASAN in uml
*/ void kasan_map_memory(void *start, size_t len)
{ if (mmap(start,
len,
PROT_READ|PROT_WRITE,
MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE,
-1,
0) == MAP_FAILED) {
os_info("Couldn't allocate shadow memory: %s\n.",
strerror(errno)); exit(1);
}
if (madvise(start, len, MADV_DONTDUMP)) {
os_info("Couldn't set MAD_DONTDUMP on shadow memory: %s\n.",
strerror(errno)); exit(1);
}
if (madvise(start, len, MADV_DONTFORK)) {
os_info("Couldn't set MADV_DONTFORK on shadow memory: %s\n.",
strerror(errno)); exit(1);
}
}
/* Set by make_tempfile() during early boot. */ char *tempdir = NULL;
/* Check if dir is on tmpfs. Return 0 if yes, -1 if no or error. */ staticint __init check_tmpfs(constchar *dir)
{ struct statfs st;
os_info("Checking if %s is on tmpfs...", dir); if (statfs(dir, &st) < 0) {
os_info("%s\n", strerror(errno));
} elseif (st.f_type != TMPFS_MAGIC) {
os_info("no\n");
} else {
os_info("OK\n"); return 0;
} return -1;
}
/* * Choose the tempdir to use. We want something on tmpfs so that our memory is * not subject to the host's vm.dirty_ratio. If a tempdir is specified in the * environment, we use that even if it's not on tmpfs, but we warn the user. * Otherwise, we try common tmpfs locations, and if no tmpfs directory is found * then we fall back to /tmp.
*/ staticchar * __init choose_tempdir(void)
{ staticconstchar * const vars[] = { "TMPDIR", "TMP", "TEMP",
NULL
}; staticconstchar fallback_dir[] = "/tmp"; staticconstchar * const tmpfs_dirs[] = { "/dev/shm",
fallback_dir,
NULL
}; int i; constchar *dir;
os_info("Checking environment variables for a tempdir..."); for (i = 0; vars[i]; i++) {
dir = getenv(vars[i]); if ((dir != NULL) && (*dir != '\0')) {
os_info("%s\n", dir); if (check_tmpfs(dir) >= 0) goto done; else goto warn;
}
}
os_info("none found\n");
for (i = 0; tmpfs_dirs[i]; i++) {
dir = tmpfs_dirs[i]; if (check_tmpfs(dir) >= 0) goto done;
}
dir = fallback_dir;
warn:
os_warn("Warning: tempdir %s is not on tmpfs\n", dir);
done: /* Make a copy since getenv results may not remain valid forever. */ return strdup(dir);
}
/* * Create an unlinked tempfile in a suitable tempdir. template must be the * basename part of the template with a leading '/'.
*/ staticint __init make_tempfile(constchar *template)
{ char *tempname; int fd;
if (tempdir == NULL) {
tempdir = choose_tempdir(); if (tempdir == NULL) {
os_warn("Failed to choose tempdir: %s\n",
strerror(errno)); return -1;
}
}
#ifdef O_TMPFILE
fd = open(tempdir, O_CLOEXEC | O_RDWR | O_EXCL | O_TMPFILE, 0700); /* * If the running system does not support O_TMPFILE flag then retry * without it.
*/ if (fd != -1 || (errno != EINVAL && errno != EISDIR &&
errno != EOPNOTSUPP)) return fd; #endif
staticint __init create_tmp_file(unsignedlonglong len)
{ int fd, err; char zero;
fd = make_tempfile(TEMPNAME_TEMPLATE); if (fd < 0) exit(1);
/* * Seek to len - 1 because writing a character there will * increase the file size by one byte, to the desired length.
*/ if (lseek64(fd, len - 1, SEEK_SET) < 0) {
perror("lseek64"); exit(1);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.