diff options
Diffstat (limited to 'tools/testing/selftests/prctl')
-rw-r--r-- | tools/testing/selftests/prctl/.gitignore | 2 | ||||
-rw-r--r-- | tools/testing/selftests/prctl/Makefile | 4 | ||||
-rw-r--r-- | tools/testing/selftests/prctl/config | 1 | ||||
-rw-r--r-- | tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/prctl/set-anon-vma-name-test.c | 104 | ||||
-rw-r--r-- | tools/testing/selftests/prctl/set-process-name.c | 94 |
7 files changed, 204 insertions, 5 deletions
diff --git a/tools/testing/selftests/prctl/.gitignore b/tools/testing/selftests/prctl/.gitignore index 91af2b631bc9..05d5e31661df 100644 --- a/tools/testing/selftests/prctl/.gitignore +++ b/tools/testing/selftests/prctl/.gitignore @@ -2,3 +2,5 @@ disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test disable-tsc-test +set-anon-vma-name-test +set-process-name diff --git a/tools/testing/selftests/prctl/Makefile b/tools/testing/selftests/prctl/Makefile index c7923b205222..01dc90fbb509 100644 --- a/tools/testing/selftests/prctl/Makefile +++ b/tools/testing/selftests/prctl/Makefile @@ -5,12 +5,10 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) ifeq ($(ARCH),x86) TEST_PROGS := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test \ - disable-tsc-test + disable-tsc-test set-anon-vma-name-test set-process-name all: $(TEST_PROGS) include ../lib.mk -clean: - rm -fr $(TEST_PROGS) endif endif diff --git a/tools/testing/selftests/prctl/config b/tools/testing/selftests/prctl/config new file mode 100644 index 000000000000..c6ed03c544e5 --- /dev/null +++ b/tools/testing/selftests/prctl/config @@ -0,0 +1 @@ +CONFIG_ANON_VMA_NAME=y diff --git a/tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c b/tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c index 62a93cc61b7c..6d1a5ee8eb28 100644 --- a/tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c +++ b/tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c @@ -79,7 +79,7 @@ int main(void) { int n_tasks = 100, i; - fprintf(stderr, "[No further output means we're allright]\n"); + fprintf(stderr, "[No further output means we're all right]\n"); for (i=0; i<n_tasks; i++) if (fork() == 0) diff --git a/tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c b/tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c index 79950f9a26fd..d39511eb9b01 100644 --- a/tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c +++ b/tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c @@ -83,7 +83,7 @@ int main(void) { int n_tasks = 100, i; - fprintf(stderr, "[No further output means we're allright]\n"); + fprintf(stderr, "[No further output means we're all right]\n"); for (i=0; i<n_tasks; i++) if (fork() == 0) diff --git a/tools/testing/selftests/prctl/set-anon-vma-name-test.c b/tools/testing/selftests/prctl/set-anon-vma-name-test.c new file mode 100644 index 000000000000..4275cb256dce --- /dev/null +++ b/tools/testing/selftests/prctl/set-anon-vma-name-test.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This test covers the anonymous VMA naming functionality through prctl calls + */ + +#include <errno.h> +#include <sys/prctl.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <string.h> + +#include "../kselftest_harness.h" + +#define AREA_SIZE 1024 + +#define GOOD_NAME "goodname" +#define BAD_NAME "badname\1" + +#ifndef PR_SET_VMA +#define PR_SET_VMA 0x53564d41 +#define PR_SET_VMA_ANON_NAME 0 +#endif + + +int rename_vma(unsigned long addr, unsigned long size, char *name) +{ + int res; + + res = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, addr, size, name); + if (res < 0) + return -errno; + return res; +} + +int was_renaming_successful(char *target_name, unsigned long ptr) +{ + FILE *maps_file; + + char line_buf[512], name[128], mode[8]; + unsigned long start_addr, end_addr, offset; + unsigned int major_id, minor_id, node_id; + + char target_buf[128]; + int res = 0, sscanf_res; + + // The entry name in maps will be in format [anon:<target_name>] + sprintf(target_buf, "[anon:%s]", target_name); + maps_file = fopen("/proc/self/maps", "r"); + if (!maps_file) { + printf("## /proc/self/maps file opening error\n"); + return 0; + } + + // Parse the maps file to find the entry we renamed + while (fgets(line_buf, sizeof(line_buf), maps_file)) { + sscanf_res = sscanf(line_buf, "%lx-%lx %7s %lx %u:%u %u %s", &start_addr, + &end_addr, mode, &offset, &major_id, + &minor_id, &node_id, name); + if (sscanf_res == EOF) { + res = 0; + printf("## EOF while parsing the maps file\n"); + break; + } + if (!strcmp(name, target_buf) && start_addr == ptr) { + res = 1; + break; + } + } + fclose(maps_file); + return res; +} + +FIXTURE(vma) { + void *ptr_anon, *ptr_not_anon; +}; + +FIXTURE_SETUP(vma) { + self->ptr_anon = mmap(NULL, AREA_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + ASSERT_NE(self->ptr_anon, NULL); + self->ptr_not_anon = mmap(NULL, AREA_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE, 0, 0); + ASSERT_NE(self->ptr_not_anon, NULL); +} + +FIXTURE_TEARDOWN(vma) { + munmap(self->ptr_anon, AREA_SIZE); + munmap(self->ptr_not_anon, AREA_SIZE); +} + +TEST_F(vma, renaming) { + TH_LOG("Try to rename the VMA with correct parameters"); + EXPECT_GE(rename_vma((unsigned long)self->ptr_anon, AREA_SIZE, GOOD_NAME), 0); + EXPECT_TRUE(was_renaming_successful(GOOD_NAME, (unsigned long)self->ptr_anon)); + + TH_LOG("Try to pass invalid name (with non-printable character \\1) to rename the VMA"); + EXPECT_EQ(rename_vma((unsigned long)self->ptr_anon, AREA_SIZE, BAD_NAME), -EINVAL); + + TH_LOG("Try to rename non-anonymous VMA"); + EXPECT_EQ(rename_vma((unsigned long) self->ptr_not_anon, AREA_SIZE, GOOD_NAME), -EINVAL); +} + +TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/prctl/set-process-name.c b/tools/testing/selftests/prctl/set-process-name.c new file mode 100644 index 000000000000..562f707ba771 --- /dev/null +++ b/tools/testing/selftests/prctl/set-process-name.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This test covers the PR_SET_NAME functionality of prctl calls + */ + +#include <errno.h> +#include <sys/prctl.h> +#include <string.h> + +#include "../kselftest_harness.h" + +#define CHANGE_NAME "changename" +#define EMPTY_NAME "" +#define TASK_COMM_LEN 16 +#define MAX_PATH_LEN 50 + +int set_name(char *name) +{ + int res; + + res = prctl(PR_SET_NAME, name, NULL, NULL, NULL); + + if (res < 0) + return -errno; + return res; +} + +int check_is_name_correct(char *check_name) +{ + char name[TASK_COMM_LEN]; + int res; + + res = prctl(PR_GET_NAME, name, NULL, NULL, NULL); + + if (res < 0) + return -errno; + + return !strcmp(name, check_name); +} + +int check_null_pointer(char *check_name) +{ + char *name = NULL; + int res; + + res = prctl(PR_GET_NAME, name, NULL, NULL, NULL); + + return res; +} + +int check_name(void) +{ + + int pid; + + pid = getpid(); + FILE *fptr = NULL; + char path[MAX_PATH_LEN] = {}; + char name[TASK_COMM_LEN] = {}; + char output[TASK_COMM_LEN] = {}; + int j; + + j = snprintf(path, MAX_PATH_LEN, "/proc/self/task/%d/comm", pid); + fptr = fopen(path, "r"); + if (!fptr) + return -EIO; + + fscanf(fptr, "%s", output); + if (ferror(fptr)) + return -EIO; + + int res = prctl(PR_GET_NAME, name, NULL, NULL, NULL); + + if (res < 0) + return -errno; + + return !strcmp(output, name); +} + +TEST(rename_process) { + + EXPECT_GE(set_name(CHANGE_NAME), 0); + EXPECT_TRUE(check_is_name_correct(CHANGE_NAME)); + + EXPECT_GE(set_name(EMPTY_NAME), 0); + EXPECT_TRUE(check_is_name_correct(EMPTY_NAME)); + + EXPECT_GE(set_name(CHANGE_NAME), 0); + EXPECT_LT(check_null_pointer(CHANGE_NAME), 0); + + EXPECT_TRUE(check_name()); +} + +TEST_HARNESS_MAIN |