cregit-Linux how code gets into the kernel

Release 4.11 arch/um/os-Linux/mem.c

Directory: arch/um/os-Linux
/*
 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 * Licensed under the GPL
 */

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/vfs.h>
#include <linux/magic.h>
#include <init.h>
#include <os.h>

/* Set by make_tempfile() during early boot. */

static char *tempdir = NULL;

/* Check if dir is on tmpfs. Return 0 if yes, -1 if no or error. */

static int __init check_tmpfs(const char *dir) { struct statfs st; printf("Checking if %s is on tmpfs...", dir); if (statfs(dir, &st) < 0) { printf("%s\n", strerror(errno)); } else if (st.f_type != TMPFS_MAGIC) { printf("no\n"); } else { printf("OK\n"); return 0; } return -1; }

Contributors

PersonTokensPropCommitsCommitProp
Tristan Schmelcher5367.95%250.00%
Jeff Dike2430.77%125.00%
Américo Wang11.28%125.00%
Total78100.00%4100.00%

/* * 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. */
static char * __init choose_tempdir(void) { static const char * const vars[] = { "TMPDIR", "TMP", "TEMP", NULL }; static const char fallback_dir[] = "/tmp"; static const char * const tmpfs_dirs[] = { "/dev/shm", fallback_dir, NULL }; int i; const char *dir; printf("Checking environment variables for a tempdir..."); for (i = 0; vars[i]; i++) { dir = getenv(vars[i]); if ((dir != NULL) && (*dir != '\0')) { printf("%s\n", dir); if (check_tmpfs(dir) >= 0) goto done; else goto warn; } } printf("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: printf("Warning: tempdir %s is not on tmpfs\n", dir); done: /* Make a copy since getenv results may not remain valid forever. */ return strdup(dir); }

Contributors

PersonTokensPropCommitsCommitProp
Tristan Schmelcher16283.94%266.67%
Rob Landley3116.06%133.33%
Total193100.00%3100.00%

/* * Create an unlinked tempfile in a suitable tempdir. template must be the * basename part of the template with a leading '/'. */
static int __init make_tempfile(const char *template) { char *tempname; int fd; if (tempdir == NULL) { tempdir = choose_tempdir(); if (tempdir == NULL) { fprintf(stderr, "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 tempname = malloc(strlen(tempdir) + strlen(template) + 1); if (tempname == NULL) return -1; strcpy(tempname, tempdir); strcat(tempname, template); fd = mkstemp(tempname); if (fd < 0) { fprintf(stderr, "open - cannot create %s: %s\n", tempname, strerror(errno)); goto out; } if (unlink(tempname) < 0) { perror("unlink"); goto close; } free(tempname); return fd; close: close(fd); out: free(tempname); return -1; }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Dike8739.37%333.33%
Mickaël Salaün4721.27%111.11%
Tristan Schmelcher4620.81%111.11%
Paolo 'Blaisorblade' Giarrusso198.60%111.11%
Jim Meyering114.98%111.11%
Davidlohr Bueso A83.62%111.11%
Américo Wang31.36%111.11%
Total221100.00%9100.00%

#define TEMPNAME_TEMPLATE "/vm_file-XXXXXX"
static int __init create_tmp_file(unsigned long long 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); } zero = 0; err = write(fd, &zero, 1); if (err != 1) { perror("write"); exit(1); } return fd; }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Dike103100.00%7100.00%
Total103100.00%7100.00%


int __init create_mem_file(unsigned long long len) { int err, fd; fd = create_tmp_file(len); err = os_set_exec_close(fd); if (err < 0) { errno = -err; perror("exec_close"); } return fd; }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Dike51100.00%3100.00%
Total51100.00%3100.00%


void __init check_tmpexec(void) { void *addr; int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); addr = mmap(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); printf("Checking PROT_EXEC mmap in %s...", tempdir); if (addr == MAP_FAILED) { err = errno; printf("%s\n", strerror(err)); close(fd); if (err == EPERM) printf("%s must be not mounted noexec\n", tempdir); exit(1); } printf("OK\n"); munmap(addr, UM_KERN_PAGE_SIZE); close(fd); }

Contributors

PersonTokensPropCommitsCommitProp
Rob Landley9988.39%125.00%
Tristan Schmelcher76.25%125.00%
Américo Wang54.46%125.00%
Jeff Dike10.89%125.00%
Total112100.00%4100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Jeff Dike30737.76%738.89%
Tristan Schmelcher27734.07%211.11%
Rob Landley13015.99%15.56%
Mickaël Salaün475.78%15.56%
Paolo 'Blaisorblade' Giarrusso192.34%15.56%
Jim Meyering111.35%15.56%
Américo Wang91.11%211.11%
Davidlohr Bueso A80.98%15.56%
Liu Aleaxander30.37%15.56%
Al Viro20.25%15.56%
Total813100.00%18100.00%
Directory: arch/um/os-Linux
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.