Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/testing/selftests/x86/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 3 kB image not shown  

Quelle  test_mremap_vdso.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * 32-bit test to check vDSO mremap.
 *
 * Copyright (c) 2016 Dmitry Safonov
 * Suggested-by: Andrew Lutomirski
 */

/*
 * Can be built statically:
 * gcc -Os -Wall -static -m32 test_mremap_vdso.c
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>

#include <sys/mman.h>
#include <sys/auxv.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include "../kselftest.h"

#define PAGE_SIZE 4096

static int try_to_remap(void *vdso_addr, unsigned long size)
{
 void *dest_addr, *new_addr;

 /* Searching for memory location where to remap */
 dest_addr = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
 if (dest_addr == MAP_FAILED) {
  ksft_print_msg("WARN: mmap failed (%d): %m\n", errno);
  return 0;
 }

 ksft_print_msg("Moving vDSO: [%p, %#lx] -> [%p, %#lx]\n",
         vdso_addr, (unsigned long)vdso_addr + size,
         dest_addr, (unsigned long)dest_addr + size);
 fflush(stdout);

 new_addr = mremap(vdso_addr, size, size,
   MREMAP_FIXED|MREMAP_MAYMOVE, dest_addr);
 if ((unsigned long)new_addr == (unsigned long)-1) {
  munmap(dest_addr, size);
  if (errno == EINVAL) {
   ksft_print_msg("vDSO partial move failed, will try with bigger size\n");
   return -1; /* Retry with larger */
  }
  ksft_print_msg("[FAIL]\tmremap failed (%d): %m\n", errno);
  return 1;
 }

 return 0;

}

#define VDSO_NAME "[vdso]"
#define VMFLAGS "VmFlags:"
#define MSEAL_FLAGS "sl"
#define MAX_LINE_LEN 512

bool vdso_sealed(FILE *maps)
{
 char line[MAX_LINE_LEN];
 bool has_vdso = false;

 while (fgets(line, sizeof(line), maps)) {
  if (strstr(line, VDSO_NAME))
   has_vdso = true;

  if (has_vdso && !strncmp(line, VMFLAGS, strlen(VMFLAGS))) {
   if (strstr(line, MSEAL_FLAGS))
    return true;

   return false;
  }
 }

 return false;
}

int main(int argc, char **argv, char **envp)
{
 pid_t child;
 FILE *maps;

 ksft_print_header();
 ksft_set_plan(1);

 maps = fopen("/proc/self/smaps""r");
 if (!maps) {
  ksft_test_result_skip(
   "Could not open /proc/self/smaps, errno=%d\n",
    errno);

  return 0;
 }

 if (vdso_sealed(maps)) {
  ksft_test_result_skip("vdso is sealed\n");
  return 0;
 }

 fclose(maps);

 child = fork();
 if (child == -1)
  ksft_exit_fail_msg("failed to fork (%d): %m\n", errno);

 if (child == 0) {
  unsigned long vdso_size = PAGE_SIZE;
  unsigned long auxval;
  int ret = -1;

  auxval = getauxval(AT_SYSINFO_EHDR);
  ksft_print_msg("AT_SYSINFO_EHDR is %#lx\n", auxval);
  if (!auxval || auxval == -ENOENT) {
   ksft_print_msg("WARN: getauxval failed\n");
   return 0;
  }

  /* Simpler than parsing ELF header */
  while (ret < 0) {
   ret = try_to_remap((void *)auxval, vdso_size);
   vdso_size += PAGE_SIZE;
  }

#ifdef __i386__
  /* Glibc is likely to explode now - exit with raw syscall */
  asm volatile ("int $0x80" : : "a" (__NR_exit), "b" (!!ret));
#else /* __x86_64__ */
  syscall(SYS_exit, ret);
#endif
 } else {
  int status;

  if (waitpid(child, &status, 0) != child ||
   !WIFEXITED(status))
   ksft_test_result_fail("mremap() of the vDSO does not work on this kernel!\n");
  else if (WEXITSTATUS(status) != 0)
   ksft_test_result_fail("Child failed with %d\n", WEXITSTATUS(status));
  else
   ksft_test_result_pass("%s\n", __func__);
 }

 ksft_finished();
}

Messung V0.5
C=97 H=92 G=94

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.