// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2021. Huawei Technologies Co., Ltd */ #include <test_progs.h> #include "strncmp_test.skel.h" static int trigger_strncmp(const struct strncmp_test *skel) { int cmp; usleep(1); cmp = skel->bss->cmp_ret; if (cmp > 0) return 1; if (cmp < 0) return -1; return 0; } /* * Compare str and target after making str[i] != target[i]. * When exp is -1, make str[i] < target[i] and delta = -1. */ static void strncmp_full_str_cmp(struct strncmp_test *skel, const char *name, int exp) { size_t nr = sizeof(skel->bss->str); char *str = skel->bss->str; int delta = exp; int got; size_t i; memcpy(str, skel->rodata->target, nr); for (i = 0; i < nr - 1; i++) { str[i] += delta; got = trigger_strncmp(skel); ASSERT_EQ(got, exp, name); str[i] -= delta; } } static void test_strncmp_ret(void) { struct strncmp_test *skel; int err, got; skel = strncmp_test__open(); if (!ASSERT_OK_PTR(skel, "strncmp_test open")) return; bpf_program__set_autoload(skel->progs.do_strncmp, true); err = strncmp_test__load(skel); if (!ASSERT_EQ(err, 0, "strncmp_test load")) goto out; err = strncmp_test__attach(skel); if (!ASSERT_EQ(err, 0, "strncmp_test attach")) goto out; skel->bss->target_pid = getpid(); /* Empty str */ skel->bss->str[0] = '\0'; got = trigger_strncmp(skel); ASSERT_EQ(got, -1, "strncmp: empty str"); /* Same string */ memcpy(skel->bss->str, skel->rodata->target, sizeof(skel->bss->str)); got = trigger_strncmp(skel); ASSERT_EQ(got, 0, "strncmp: same str"); /* Not-null-termainted string */ memcpy(skel->bss->str, skel->rodata->target, sizeof(skel->bss->str)); skel->bss->str[sizeof(skel->bss->str) - 1] = 'A'; got = trigger_strncmp(skel); ASSERT_EQ(got, 1, "strncmp: not-null-term str"); strncmp_full_str_cmp(skel, "strncmp: less than", -1); strncmp_full_str_cmp(skel, "strncmp: greater than", 1); out: strncmp_test__destroy(skel); } static void test_strncmp_bad_not_const_str_size(void) { struct strncmp_test *skel; int err; skel = strncmp_test__open(); if (!ASSERT_OK_PTR(skel, "strncmp_test open")) return; bpf_program__set_autoload(skel->progs.strncmp_bad_not_const_str_size, true); err = strncmp_test__load(skel); ASSERT_ERR(err, "strncmp_test load bad_not_const_str_size"); strncmp_test__destroy(skel); } static void test_strncmp_bad_writable_target(void) { struct strncmp_test *skel; int err; skel = strncmp_test__open(); if (!ASSERT_OK_PTR(skel, "strncmp_test open")) return; bpf_program__set_autoload(skel->progs.strncmp_bad_writable_target, true); err = strncmp_test__load(skel); ASSERT_ERR(err, "strncmp_test load bad_writable_target"); strncmp_test__destroy(skel); } static void test_strncmp_bad_not_null_term_target(void) { struct strncmp_test *skel; int err; skel = strncmp_test__open(); if (!ASSERT_OK_PTR(skel, "strncmp_test open")) return; bpf_program__set_autoload(skel->progs.strncmp_bad_not_null_term_target, true); err = strncmp_test__load(skel); ASSERT_ERR(err, "strncmp_test load bad_not_null_term_target"); strncmp_test__destroy(skel); } void test_test_strncmp(void) { if (test__start_subtest("strncmp_ret")) test_strncmp_ret(); if (test__start_subtest("strncmp_bad_not_const_str_size")) test_strncmp_bad_not_const_str_size(); if (test__start_subtest("strncmp_bad_writable_target")) test_strncmp_bad_writable_target(); if (test__start_subtest("strncmp_bad_not_null_term_target")) test_strncmp_bad_not_null_term_target(); }