ATF_TC_BODY(mlock_limits, tc) { struct rlimit res; void *buf; pid_t pid; int sta; buf = malloc(page); ATF_REQUIRE(buf != NULL); pid = fork(); ATF_REQUIRE(pid >= 0); if (pid == 0) { for (ssize_t i = page; i >= 2; i -= 100) { res.rlim_cur = i - 1; res.rlim_max = i - 1; (void)fprintf(stderr, "trying to lock %zd bytes " "with %zu byte limit\n", i, (size_t)res.rlim_cur); if (setrlimit(RLIMIT_MEMLOCK, &res) != 0) _exit(EXIT_FAILURE); errno = 0; #ifdef __FreeBSD__ /* * NetBSD doesn't conform to POSIX with ENOMEM requirement; * FreeBSD does. * * See: NetBSD PR # kern/48962 for more details. */ if (mlock(buf, i) != -1 || errno != ENOMEM) { #else if (mlock(buf, i) != -1 || errno != EAGAIN) { #endif (void)munlock(buf, i); _exit(EXIT_FAILURE); } } _exit(EXIT_SUCCESS); } (void)wait(&sta); if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) atf_tc_fail("mlock(2) locked beyond system limits"); free(buf); } ATF_TC(mlock_mmap); ATF_TC_HEAD(mlock_mmap, tc) { atf_tc_set_md_var(tc, "descr", "Test mlock(2)-mmap(2) interaction"); }
ATF_TC_BODY(bpfjit_extmem_side_effect, tc) { static struct bpf_insn insns[] = { BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A <- P[0] */ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */ BPF_STMT(BPF_ST, 1), /* M[1] <- A */ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ BPF_STMT(BPF_STX, 2), /* M[2] <- X */ BPF_STMT(BPF_ST, 3), /* M[3] <- A */ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99), /* A <- P[99] */ BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */ }; bpfjit_func_t code; uint8_t pkt[1] = { 1 }; uint32_t mem[ctx.extwords]; /* Pre-inited words. */ mem[0] = 0; mem[3] = 7; mem[1] = mem[2] = 0xdeadbeef; bpf_args_t args = { .pkt = pkt, .buflen = sizeof(pkt), .wirelen = sizeof(pkt), .mem = mem, }; size_t insn_count = sizeof(insns) / sizeof(insns[0]); RZ(rump_init()); rump_schedule(); code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); rump_unschedule(); ATF_REQUIRE(code != NULL); ATF_CHECK(code(&ctx, &args) == 0); rump_schedule(); rumpns_bpfjit_free_code(code); rump_unschedule(); ATF_CHECK(mem[0] == 0); ATF_CHECK(mem[1] == 1); ATF_CHECK(mem[2] == 2); ATF_CHECK(mem[3] == 3); } ATF_TC(bpfjit_extmem_invalid_store); ATF_TC_HEAD(bpfjit_extmem_invalid_store, tc) { atf_tc_set_md_var(tc, "descr", "Test that out-of-range store " "fails validation"); }
ATF_TC_BODY(bpfjit_copx_ret_mem, tc) { static struct bpf_insn insns[] = { BPF_STMT(BPF_LD+BPF_IMM, 13), BPF_STMT(BPF_ST, 2), BPF_STMT(BPF_LD+BPF_IMM, 137), BPF_STMT(BPF_ST, 1), BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM BPF_STMT(BPF_MISC+BPF_COPX, 0), BPF_STMT(BPF_RET+BPF_A, 0) }; bpfjit_func_t code; uint8_t pkt[1] = { 0 }; uint32_t mem[ctx.extwords]; void *arg = (void*)(uintptr_t)2; /* Pre-inited words. */ mem[0] = 0; mem[3] = 3; bpf_args_t args = { .pkt = pkt, .buflen = sizeof(pkt), .wirelen = sizeof(pkt), .arg = arg, .mem = mem, }; size_t insn_count = sizeof(insns) / sizeof(insns[0]); RZ(rump_init()); rump_schedule(); code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); rump_unschedule(); ATF_REQUIRE(code != NULL); ATF_CHECK(code(&ctx, &args) == 13); rump_schedule(); rumpns_bpfjit_free_code(code); rump_unschedule(); } ATF_TC(bpfjit_copx_ret_preinited_mem); ATF_TC_HEAD(bpfjit_copx_ret_preinited_mem, tc) { atf_tc_set_md_var(tc, "descr", "Test coprocessor function that " "returns a content of external pre-initialized memory word"); }
ATF_TC_BODY(init_pack, tcin) { atf_tc_t tc; atf_tc_pack_t tcp1 = { .m_ident = "test1", .m_head = ATF_TC_HEAD_NAME(empty), .m_body = ATF_TC_BODY_NAME(empty), .m_cleanup = NULL, }; atf_tc_pack_t tcp2 = { .m_ident = "test2", .m_head = ATF_TC_HEAD_NAME(test_var), .m_body = ATF_TC_BODY_NAME(empty), .m_cleanup = NULL, }; RE(atf_tc_init_pack(&tc, &tcp1, NULL)); ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test1") == 0); ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var")); atf_tc_fini(&tc); RE(atf_tc_init_pack(&tc, &tcp2, NULL)); ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test2") == 0); ATF_REQUIRE(atf_tc_has_md_var(&tc, "test-var")); atf_tc_fini(&tc); } ATF_TC(vars); ATF_TC_HEAD(vars, tc) { atf_tc_set_md_var(tc, "descr", "Tests the atf_tc_get_md_var, " "atf_tc_has_md_var and atf_tc_set_md_var functions"); } ATF_TC_BODY(vars, tcin) { atf_tc_t tc; RE(atf_tc_init(&tc, "test1", ATF_TC_HEAD_NAME(empty), ATF_TC_BODY_NAME(empty), NULL, NULL)); ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var")); RE(atf_tc_set_md_var(&tc, "test-var", "Test value")); ATF_REQUIRE(atf_tc_has_md_var(&tc, "test-var")); ATF_REQUIRE(strcmp(atf_tc_get_md_var(&tc, "test-var"), "Test value") == 0); atf_tc_fini(&tc); }
ATF_TC_BODY(bpfjit_extmem_load_preinited, tc) { static struct bpf_insn insns[] = { BPF_STMT(BPF_LD+BPF_MEM, 3), BPF_STMT(BPF_RET+BPF_A, 0) }; bpfjit_func_t code; uint8_t pkt[1] = { 0 }; uint32_t mem[ctx.extwords]; /* Pre-inited words. */ mem[0] = 0; mem[3] = 3; bpf_args_t args = { .pkt = pkt, .buflen = sizeof(pkt), .wirelen = sizeof(pkt), .mem = mem, }; size_t insn_count = sizeof(insns) / sizeof(insns[0]); RZ(rump_init()); rump_schedule(); code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); rump_unschedule(); ATF_REQUIRE(code != NULL); ATF_CHECK(code(&ctx, &args) == 3); rump_schedule(); rumpns_bpfjit_free_code(code); rump_unschedule(); } ATF_TC(bpfjit_extmem_invalid_load); ATF_TC_HEAD(bpfjit_extmem_invalid_load, tc) { atf_tc_set_md_var(tc, "descr", "Test that out-of-range load " "fails validation"); }
ATF_TC_BODY(good_big5_getwc, tc) { const char buf[] = { 0xcf, 0x40 }; struct ibuf ib = { .buf = buf, .buflen = sizeof(buf), }; FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL); ATF_REQUIRE(fp != NULL); setlocale(LC_CTYPE, "zh_TW.Big5"); /* XXX implementation detail knowledge (wchar_t encoding) */ ATF_REQUIRE_EQ(getwc(fp), 0xcf40); fclose(fp); } ATF_TC(bad_big5_getwc); ATF_TC_HEAD(bad_big5_getwc, tc) { atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar getwc"); }