/
githubmirror
/
ndctl
Обзор
Документация
Войти
/
githubmirror
/
ndctl
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
test/revoke-devmem.c
143 строки
3 KB
Dan Williams
util: Distribute 'filter' and 'json' helpers to per-tool objects
14 янв 2022, 01:17
14 янв 2022, 01:17
965fa02
Код
Авторство
О чём код?
// SPDX-License-Identifier: GPL-2.0-only /* Copyright (C) 2020 Intel Corporation. All rights reserved. */ #include <fcntl.h> #include <stdio.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #include <syslog.h> #include <string.h> #include <signal.h> #include <setjmp.h> #include <sys/stat.h> #include <sys/mman.h> #include <sys/time.h> #include <sys/types.h> #include <util/size.h> #include <linux/falloc.h> #include <linux/version.h> #include <ndctl/libndctl.h> #include <ccan/array_size/array_size.h> #include <ndctl/builtin.h> #include <test.h> static sigjmp_buf sj_env; static void sigbus(int sig, siginfo_t *siginfo, void *d) { siglongjmp(sj_env, 1); } #define err(fmt, ...) \ fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) static int test_devmem(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx) { void *buf; int fd, rc; struct sigaction act; unsigned long long resource; struct ndctl_namespace *ndns; ndctl_set_log_priority(ctx, loglevel); /* iostrict devmem started in kernel 4.5 */ if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 5, 0))) return 77; ndns = ndctl_get_test_dev(ctx); if (!ndns) { err("failed to find suitable namespace\n"); return 77; } resource = ndctl_namespace_get_resource(ndns); if (resource == ULLONG_MAX) { err("failed to retrieve resource base\n"); return 77; } rc = ndctl_namespace_disable(ndns); if (rc) { err("failed to disable namespace\n"); return rc; } /* establish a devmem mapping of the namespace memory */ fd = open("/dev/mem", O_RDWR); if (fd < 0) { err("failed to open /dev/mem: %s\n", strerror(errno)); rc = -errno; goto out_devmem; } buf = mmap(NULL, SZ_2M, PROT_READ|PROT_WRITE, MAP_SHARED, fd, resource); if (buf == MAP_FAILED) { err("failed to map /dev/mem: %s\n", strerror(errno)); rc = -errno; goto out_mmap; } /* populate and write, should not fail */ memset(buf, 0, SZ_2M); memset(&act, 0, sizeof(act)); act.sa_sigaction = sigbus; act.sa_flags = SA_SIGINFO; if (sigaction(SIGBUS, &act, 0)) { perror("sigaction"); rc = EXIT_FAILURE; goto out_sigaction; } /* test fault due to devmem revocation */ if (sigsetjmp(sj_env, 1)) { /* got sigbus, success */ fprintf(stderr, "devmem revoked!\n"); rc = 0; goto out_sigaction; } rc = ndctl_namespace_enable(ndns); if (rc) { err("failed to enable namespace\n"); goto out_sigaction; } /* write, should sigbus */ memset(buf, 0, SZ_2M); err("kernel failed to prevent write after namespace enabled\n"); rc = -ENXIO; out_sigaction: munmap(buf, SZ_2M); out_mmap: close(fd); out_devmem: if (ndctl_namespace_enable(ndns) != 0) err("failed to re-enable namespace\n"); return rc; } int main(int argc, char *argv[]) { struct ndctl_test *test = ndctl_test_new(0); struct ndctl_ctx *ctx; int rc; if (!test) { fprintf(stderr, "failed to initialize test\n"); return EXIT_FAILURE; } rc = ndctl_new(&ctx); if (rc < 0) return ndctl_test_result(test, rc); rc = test_devmem(LOG_DEBUG, test, ctx); ndctl_unref(ctx); return ndctl_test_result(test, rc); }