brintos

brintos / linux-shallow public Read only

0
0
Text · 15.6 KiB · 516f4a1 Raw
410 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <test_progs.h>3#include <network_helpers.h>4 5#include "exceptions.skel.h"6#include "exceptions_ext.skel.h"7#include "exceptions_fail.skel.h"8#include "exceptions_assert.skel.h"9 10static char log_buf[1024 * 1024];11 12static void test_exceptions_failure(void)13{14	RUN_TESTS(exceptions_fail);15}16 17static void test_exceptions_success(void)18{19	LIBBPF_OPTS(bpf_test_run_opts, ropts,20		.data_in = &pkt_v4,21		.data_size_in = sizeof(pkt_v4),22		.repeat = 1,23	);24	struct exceptions_ext *eskel = NULL;25	struct exceptions *skel;26	int ret;27 28	skel = exceptions__open();29	if (!ASSERT_OK_PTR(skel, "exceptions__open"))30		return;31 32	ret = exceptions__load(skel);33	if (!ASSERT_OK(ret, "exceptions__load"))34		goto done;35 36	if (!ASSERT_OK(bpf_map_update_elem(bpf_map__fd(skel->maps.jmp_table), &(int){0},37					   &(int){bpf_program__fd(skel->progs.exception_tail_call_target)}, BPF_ANY),38		       "bpf_map_update_elem jmp_table"))39		goto done;40 41#define RUN_SUCCESS(_prog, return_val)						  \42	if (!test__start_subtest(#_prog)) goto _prog##_##return_val;		  \43	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs._prog), &ropts); \44	ASSERT_OK(ret, #_prog " prog run ret");					  \45	ASSERT_EQ(ropts.retval, return_val, #_prog " prog run retval");		  \46	_prog##_##return_val:47 48	RUN_SUCCESS(exception_throw_always_1, 64);49	RUN_SUCCESS(exception_throw_always_2, 32);50	RUN_SUCCESS(exception_throw_unwind_1, 16);51	RUN_SUCCESS(exception_throw_unwind_2, 32);52	RUN_SUCCESS(exception_throw_default, 0);53	RUN_SUCCESS(exception_throw_default_value, 5);54	RUN_SUCCESS(exception_tail_call, 24);55	RUN_SUCCESS(exception_ext, 0);56	RUN_SUCCESS(exception_ext_mod_cb_runtime, 35);57	RUN_SUCCESS(exception_throw_subprog, 1);58	RUN_SUCCESS(exception_assert_nz_gfunc, 1);59	RUN_SUCCESS(exception_assert_zero_gfunc, 1);60	RUN_SUCCESS(exception_assert_neg_gfunc, 1);61	RUN_SUCCESS(exception_assert_pos_gfunc, 1);62	RUN_SUCCESS(exception_assert_negeq_gfunc, 1);63	RUN_SUCCESS(exception_assert_poseq_gfunc, 1);64	RUN_SUCCESS(exception_assert_nz_gfunc_with, 1);65	RUN_SUCCESS(exception_assert_zero_gfunc_with, 1);66	RUN_SUCCESS(exception_assert_neg_gfunc_with, 1);67	RUN_SUCCESS(exception_assert_pos_gfunc_with, 1);68	RUN_SUCCESS(exception_assert_negeq_gfunc_with, 1);69	RUN_SUCCESS(exception_assert_poseq_gfunc_with, 1);70	RUN_SUCCESS(exception_bad_assert_nz_gfunc, 0);71	RUN_SUCCESS(exception_bad_assert_zero_gfunc, 0);72	RUN_SUCCESS(exception_bad_assert_neg_gfunc, 0);73	RUN_SUCCESS(exception_bad_assert_pos_gfunc, 0);74	RUN_SUCCESS(exception_bad_assert_negeq_gfunc, 0);75	RUN_SUCCESS(exception_bad_assert_poseq_gfunc, 0);76	RUN_SUCCESS(exception_bad_assert_nz_gfunc_with, 100);77	RUN_SUCCESS(exception_bad_assert_zero_gfunc_with, 105);78	RUN_SUCCESS(exception_bad_assert_neg_gfunc_with, 200);79	RUN_SUCCESS(exception_bad_assert_pos_gfunc_with, 0);80	RUN_SUCCESS(exception_bad_assert_negeq_gfunc_with, 101);81	RUN_SUCCESS(exception_bad_assert_poseq_gfunc_with, 99);82	RUN_SUCCESS(exception_assert_range, 1);83	RUN_SUCCESS(exception_assert_range_with, 1);84	RUN_SUCCESS(exception_bad_assert_range, 0);85	RUN_SUCCESS(exception_bad_assert_range_with, 10);86 87#define RUN_EXT(load_ret, attach_err, expr, msg, after_link)			  \88	{									  \89		LIBBPF_OPTS(bpf_object_open_opts, o, .kernel_log_buf = log_buf,		 \90						     .kernel_log_size = sizeof(log_buf), \91						     .kernel_log_level = 2);		 \92		exceptions_ext__destroy(eskel);					  \93		eskel = exceptions_ext__open_opts(&o);				  \94		struct bpf_program *prog = NULL;				  \95		struct bpf_link *link = NULL;					  \96		if (!ASSERT_OK_PTR(eskel, "exceptions_ext__open"))		  \97			goto done;						  \98		(expr);								  \99		ASSERT_OK_PTR(bpf_program__name(prog), bpf_program__name(prog));  \100		if (!ASSERT_EQ(exceptions_ext__load(eskel), load_ret,		  \101			       "exceptions_ext__load"))	{			  \102			printf("%s\n", log_buf);				  \103			goto done;						  \104		}								  \105		if (load_ret != 0) {						  \106			if (!ASSERT_OK_PTR(strstr(log_buf, msg), "strstr")) {	  \107				printf("%s\n", log_buf);			  \108				goto done;					  \109			}							  \110		}								  \111		if (!load_ret && attach_err) {					  \112			if (!ASSERT_ERR_PTR(link = bpf_program__attach(prog), "attach err")) \113				goto done;					  \114		} else if (!load_ret) {						  \115			if (!ASSERT_OK_PTR(link = bpf_program__attach(prog), "attach ok"))  \116				goto done;					  \117			(void)(after_link);					  \118			bpf_link__destroy(link);				  \119		}								  \120	}121 122	if (test__start_subtest("non-throwing fentry -> exception_cb"))123		RUN_EXT(-EINVAL, true, ({124			prog = eskel->progs.pfentry;125			bpf_program__set_autoload(prog, true);126			if (!ASSERT_OK(bpf_program__set_attach_target(prog,127				       bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),128				       "exception_cb_mod"), "set_attach_target"))129				goto done;130		}), "FENTRY/FEXIT programs cannot attach to exception callback", 0);131 132	if (test__start_subtest("throwing fentry -> exception_cb"))133		RUN_EXT(-EINVAL, true, ({134			prog = eskel->progs.throwing_fentry;135			bpf_program__set_autoload(prog, true);136			if (!ASSERT_OK(bpf_program__set_attach_target(prog,137				       bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),138				       "exception_cb_mod"), "set_attach_target"))139				goto done;140		}), "FENTRY/FEXIT programs cannot attach to exception callback", 0);141 142	if (test__start_subtest("non-throwing fexit -> exception_cb"))143		RUN_EXT(-EINVAL, true, ({144			prog = eskel->progs.pfexit;145			bpf_program__set_autoload(prog, true);146			if (!ASSERT_OK(bpf_program__set_attach_target(prog,147				       bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),148				       "exception_cb_mod"), "set_attach_target"))149				goto done;150		}), "FENTRY/FEXIT programs cannot attach to exception callback", 0);151 152	if (test__start_subtest("throwing fexit -> exception_cb"))153		RUN_EXT(-EINVAL, true, ({154			prog = eskel->progs.throwing_fexit;155			bpf_program__set_autoload(prog, true);156			if (!ASSERT_OK(bpf_program__set_attach_target(prog,157				       bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),158				       "exception_cb_mod"), "set_attach_target"))159				goto done;160		}), "FENTRY/FEXIT programs cannot attach to exception callback", 0);161 162	if (test__start_subtest("throwing extension (with custom cb) -> exception_cb"))163		RUN_EXT(-EINVAL, true, ({164			prog = eskel->progs.throwing_exception_cb_extension;165			bpf_program__set_autoload(prog, true);166			if (!ASSERT_OK(bpf_program__set_attach_target(prog,167				       bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),168				       "exception_cb_mod"), "set_attach_target"))169				goto done;170		}), "Extension programs cannot attach to exception callback", 0);171 172	if (test__start_subtest("throwing extension -> global func in exception_cb"))173		RUN_EXT(0, false, ({174			prog = eskel->progs.throwing_exception_cb_extension;175			bpf_program__set_autoload(prog, true);176			if (!ASSERT_OK(bpf_program__set_attach_target(prog,177				       bpf_program__fd(skel->progs.exception_ext_mod_cb_runtime),178				       "exception_cb_mod_global"), "set_attach_target"))179				goto done;180		}), "", ({ RUN_SUCCESS(exception_ext_mod_cb_runtime, 131); }));181 182	if (test__start_subtest("throwing extension (with custom cb) -> global func in exception_cb"))183		RUN_EXT(0, false, ({184			prog = eskel->progs.throwing_extension;185			bpf_program__set_autoload(prog, true);186			if (!ASSERT_OK(bpf_program__set_attach_target(prog,187				       bpf_program__fd(skel->progs.exception_ext),188				       "exception_ext_global"), "set_attach_target"))189				goto done;190		}), "", ({ RUN_SUCCESS(exception_ext, 128); }));191 192	if (test__start_subtest("non-throwing fentry -> non-throwing subprog"))193		/* non-throwing fentry -> non-throwing subprog : OK */194		RUN_EXT(0, false, ({195			prog = eskel->progs.pfentry;196			bpf_program__set_autoload(prog, true);197			if (!ASSERT_OK(bpf_program__set_attach_target(prog,198				       bpf_program__fd(skel->progs.exception_throw_subprog),199				       "subprog"), "set_attach_target"))200				goto done;201		}), "", 0);202 203	if (test__start_subtest("throwing fentry -> non-throwing subprog"))204		/* throwing fentry -> non-throwing subprog : OK */205		RUN_EXT(0, false, ({206			prog = eskel->progs.throwing_fentry;207			bpf_program__set_autoload(prog, true);208			if (!ASSERT_OK(bpf_program__set_attach_target(prog,209				       bpf_program__fd(skel->progs.exception_throw_subprog),210				       "subprog"), "set_attach_target"))211				goto done;212		}), "", 0);213 214	if (test__start_subtest("non-throwing fentry -> throwing subprog"))215		/* non-throwing fentry -> throwing subprog : OK */216		RUN_EXT(0, false, ({217			prog = eskel->progs.pfentry;218			bpf_program__set_autoload(prog, true);219			if (!ASSERT_OK(bpf_program__set_attach_target(prog,220				       bpf_program__fd(skel->progs.exception_throw_subprog),221				       "throwing_subprog"), "set_attach_target"))222				goto done;223		}), "", 0);224 225	if (test__start_subtest("throwing fentry -> throwing subprog"))226		/* throwing fentry -> throwing subprog : OK */227		RUN_EXT(0, false, ({228			prog = eskel->progs.throwing_fentry;229			bpf_program__set_autoload(prog, true);230			if (!ASSERT_OK(bpf_program__set_attach_target(prog,231				       bpf_program__fd(skel->progs.exception_throw_subprog),232				       "throwing_subprog"), "set_attach_target"))233				goto done;234		}), "", 0);235 236	if (test__start_subtest("non-throwing fexit -> non-throwing subprog"))237		/* non-throwing fexit -> non-throwing subprog : OK */238		RUN_EXT(0, false, ({239			prog = eskel->progs.pfexit;240			bpf_program__set_autoload(prog, true);241			if (!ASSERT_OK(bpf_program__set_attach_target(prog,242				       bpf_program__fd(skel->progs.exception_throw_subprog),243				       "subprog"), "set_attach_target"))244				goto done;245		}), "", 0);246 247	if (test__start_subtest("throwing fexit -> non-throwing subprog"))248		/* throwing fexit -> non-throwing subprog : OK */249		RUN_EXT(0, false, ({250			prog = eskel->progs.throwing_fexit;251			bpf_program__set_autoload(prog, true);252			if (!ASSERT_OK(bpf_program__set_attach_target(prog,253				       bpf_program__fd(skel->progs.exception_throw_subprog),254				       "subprog"), "set_attach_target"))255				goto done;256		}), "", 0);257 258	if (test__start_subtest("non-throwing fexit -> throwing subprog"))259		/* non-throwing fexit -> throwing subprog : OK */260		RUN_EXT(0, false, ({261			prog = eskel->progs.pfexit;262			bpf_program__set_autoload(prog, true);263			if (!ASSERT_OK(bpf_program__set_attach_target(prog,264				       bpf_program__fd(skel->progs.exception_throw_subprog),265				       "throwing_subprog"), "set_attach_target"))266				goto done;267		}), "", 0);268 269	if (test__start_subtest("throwing fexit -> throwing subprog"))270		/* throwing fexit -> throwing subprog : OK */271		RUN_EXT(0, false, ({272			prog = eskel->progs.throwing_fexit;273			bpf_program__set_autoload(prog, true);274			if (!ASSERT_OK(bpf_program__set_attach_target(prog,275				       bpf_program__fd(skel->progs.exception_throw_subprog),276				       "throwing_subprog"), "set_attach_target"))277				goto done;278		}), "", 0);279 280	/* fmod_ret not allowed for subprog - Check so we remember to handle its281	 * throwing specification compatibility with target when supported.282	 */283	if (test__start_subtest("non-throwing fmod_ret -> non-throwing subprog"))284		RUN_EXT(-EINVAL, true, ({285			prog = eskel->progs.pfmod_ret;286			bpf_program__set_autoload(prog, true);287			if (!ASSERT_OK(bpf_program__set_attach_target(prog,288				       bpf_program__fd(skel->progs.exception_throw_subprog),289				       "subprog"), "set_attach_target"))290				goto done;291		}), "can't modify return codes of BPF program", 0);292 293	/* fmod_ret not allowed for subprog - Check so we remember to handle its294	 * throwing specification compatibility with target when supported.295	 */296	if (test__start_subtest("non-throwing fmod_ret -> non-throwing global subprog"))297		RUN_EXT(-EINVAL, true, ({298			prog = eskel->progs.pfmod_ret;299			bpf_program__set_autoload(prog, true);300			if (!ASSERT_OK(bpf_program__set_attach_target(prog,301				       bpf_program__fd(skel->progs.exception_throw_subprog),302				       "global_subprog"), "set_attach_target"))303				goto done;304		}), "can't modify return codes of BPF program", 0);305 306	if (test__start_subtest("non-throwing extension -> non-throwing subprog"))307		/* non-throwing extension -> non-throwing subprog : BAD (!global) */308		RUN_EXT(-EINVAL, true, ({309			prog = eskel->progs.extension;310			bpf_program__set_autoload(prog, true);311			if (!ASSERT_OK(bpf_program__set_attach_target(prog,312				       bpf_program__fd(skel->progs.exception_throw_subprog),313				       "subprog"), "set_attach_target"))314				goto done;315		}), "subprog() is not a global function", 0);316 317	if (test__start_subtest("non-throwing extension -> throwing subprog"))318		/* non-throwing extension -> throwing subprog : BAD (!global) */319		RUN_EXT(-EINVAL, true, ({320			prog = eskel->progs.extension;321			bpf_program__set_autoload(prog, true);322			if (!ASSERT_OK(bpf_program__set_attach_target(prog,323				       bpf_program__fd(skel->progs.exception_throw_subprog),324				       "throwing_subprog"), "set_attach_target"))325				goto done;326		}), "throwing_subprog() is not a global function", 0);327 328	if (test__start_subtest("non-throwing extension -> non-throwing subprog"))329		/* non-throwing extension -> non-throwing global subprog : OK */330		RUN_EXT(0, false, ({331			prog = eskel->progs.extension;332			bpf_program__set_autoload(prog, true);333			if (!ASSERT_OK(bpf_program__set_attach_target(prog,334				       bpf_program__fd(skel->progs.exception_throw_subprog),335				       "global_subprog"), "set_attach_target"))336				goto done;337		}), "", 0);338 339	if (test__start_subtest("non-throwing extension -> throwing global subprog"))340		/* non-throwing extension -> throwing global subprog : OK */341		RUN_EXT(0, false, ({342			prog = eskel->progs.extension;343			bpf_program__set_autoload(prog, true);344			if (!ASSERT_OK(bpf_program__set_attach_target(prog,345				       bpf_program__fd(skel->progs.exception_throw_subprog),346				       "throwing_global_subprog"), "set_attach_target"))347				goto done;348		}), "", 0);349 350	if (test__start_subtest("throwing extension -> throwing global subprog"))351		/* throwing extension -> throwing global subprog : OK */352		RUN_EXT(0, false, ({353			prog = eskel->progs.throwing_extension;354			bpf_program__set_autoload(prog, true);355			if (!ASSERT_OK(bpf_program__set_attach_target(prog,356				       bpf_program__fd(skel->progs.exception_throw_subprog),357				       "throwing_global_subprog"), "set_attach_target"))358				goto done;359		}), "", 0);360 361	if (test__start_subtest("throwing extension -> non-throwing global subprog"))362		/* throwing extension -> non-throwing global subprog : OK */363		RUN_EXT(0, false, ({364			prog = eskel->progs.throwing_extension;365			bpf_program__set_autoload(prog, true);366			if (!ASSERT_OK(bpf_program__set_attach_target(prog,367				       bpf_program__fd(skel->progs.exception_throw_subprog),368				       "global_subprog"), "set_attach_target"))369				goto done;370		}), "", 0);371 372	if (test__start_subtest("non-throwing extension -> main subprog"))373		/* non-throwing extension -> main subprog : OK */374		RUN_EXT(0, false, ({375			prog = eskel->progs.extension;376			bpf_program__set_autoload(prog, true);377			if (!ASSERT_OK(bpf_program__set_attach_target(prog,378				       bpf_program__fd(skel->progs.exception_throw_subprog),379				       "exception_throw_subprog"), "set_attach_target"))380				goto done;381		}), "", 0);382 383	if (test__start_subtest("throwing extension -> main subprog"))384		/* throwing extension -> main subprog : OK */385		RUN_EXT(0, false, ({386			prog = eskel->progs.throwing_extension;387			bpf_program__set_autoload(prog, true);388			if (!ASSERT_OK(bpf_program__set_attach_target(prog,389				       bpf_program__fd(skel->progs.exception_throw_subprog),390				       "exception_throw_subprog"), "set_attach_target"))391				goto done;392		}), "", 0);393 394done:395	exceptions_ext__destroy(eskel);396	exceptions__destroy(skel);397}398 399static void test_exceptions_assertions(void)400{401	RUN_TESTS(exceptions_assert);402}403 404void test_exceptions(void)405{406	test_exceptions_success();407	test_exceptions_failure();408	test_exceptions_assertions();409}410