Contributors: 15
Author Tokens Token Proportion Commits Commit Proportion
Jakub Kiciński 9647 69.60% 4 10.00%
Daniel Borkmann 2308 16.65% 9 22.50%
Alexei Starovoitov 719 5.19% 6 15.00%
Kumar Kartikeya Dwivedi 685 4.94% 6 15.00%
Eduard Zingerman 298 2.15% 2 5.00%
Paul Chaignon 134 0.97% 2 5.00%
David Vernet 29 0.21% 1 2.50%
Tengda Wu 14 0.10% 1 2.50%
Yonghong Song 8 0.06% 1 2.50%
Martin KaFai Lau 6 0.04% 1 2.50%
Andrii Nakryiko 4 0.03% 2 5.00%
Mykola Lysenko 3 0.02% 1 2.50%
Andrei Matei 3 0.02% 2 5.00%
Maxim Mikityanskiy 1 0.01% 1 2.50%
Colin Ian King 1 0.01% 1 2.50%
Total 13860 40

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411
{
	"calls: invalid kfunc call not eliminated",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.result  = REJECT,
	.errstr = "invalid kernel function call not eliminated in verifier pass",
},
{
	"calls: invalid kfunc call unreachable",
	.insns = {
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 0, 2),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.result  = ACCEPT,
},
{
	"calls: invalid kfunc call: ptr_to_mem to struct with non-scalar",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = REJECT,
	.errstr = "arg#0 pointer type STRUCT prog_test_fail1 must point to scalar",
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_fail1", 2 },
	},
},
{
	"calls: invalid kfunc call: ptr_to_mem to struct with nesting depth > 4",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = REJECT,
	.errstr = "max struct nesting depth exceeded\narg#0 pointer type STRUCT prog_test_fail2",
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_fail2", 2 },
	},
},
{
	"calls: invalid kfunc call: ptr_to_mem to struct with FAM",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = REJECT,
	.errstr = "arg#0 pointer type STRUCT prog_test_fail3 must point to scalar",
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_fail3", 2 },
	},
},
{
	"calls: invalid kfunc call: reg->type != PTR_TO_CTX",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = REJECT,
	.errstr = "arg#0 expected pointer to ctx, but got fp",
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_pass_ctx", 2 },
	},
},
{
	"calls: invalid kfunc call: void * not allowed in func proto without mem size arg",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = REJECT,
	.errstr = "arg#0 pointer type UNKNOWN  must point to scalar",
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_mem_len_fail1", 2 },
	},
},
{
	"calls: trigger reg2btf_ids[reg->type] for reg->type > __BPF_REG_TYPE_MAX",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = REJECT,
	.errstr = "Possibly NULL pointer passed to trusted arg0",
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_acquire", 3 },
		{ "bpf_kfunc_call_test_release", 5 },
	},
},
{
	"calls: invalid kfunc call: reg->off must be zero when passed to release kfunc",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_EXIT_INSN(),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = REJECT,
	.errstr = "R1 must have zero offset when passed to release func",
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_acquire", 3 },
		{ "bpf_kfunc_call_memb_release", 8 },
	},
},
{
	"calls: invalid kfunc call: don't match first member type when passed to release kfunc",
	.insns = {
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = REJECT,
	.errstr = "kernel function bpf_kfunc_call_memb1_release args#0 expected pointer",
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_memb_acquire", 1 },
		{ "bpf_kfunc_call_memb1_release", 5 },
	},
},
{
	"calls: invalid kfunc call: PTR_TO_BTF_ID with negative offset",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -4),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_acquire", 3 },
		{ "bpf_kfunc_call_test_offset", 9 },
		{ "bpf_kfunc_call_test_release", 12 },
	},
	.result_unpriv = REJECT,
	.result = REJECT,
	.errstr = "ptr R1 off=-4 disallowed",
},
{
	"calls: invalid kfunc call: PTR_TO_BTF_ID with variable offset",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
	BPF_JMP_IMM(BPF_JLE, BPF_REG_2, 4, 3),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 3),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_acquire", 3 },
		{ "bpf_kfunc_call_test_release", 9 },
		{ "bpf_kfunc_call_test_release", 13 },
		{ "bpf_kfunc_call_test_release", 17 },
	},
	.result_unpriv = REJECT,
	.result = REJECT,
	.errstr = "variable ptr_ access var_off=(0x0; 0x7) disallowed",
},
{
	"calls: invalid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_acquire", 3 },
		{ "bpf_kfunc_call_test_ref", 8 },
		{ "bpf_kfunc_call_test_ref", 10 },
	},
	.result_unpriv = REJECT,
	.result = REJECT,
	.errstr = "R1 must be",
},
{
	"calls: valid kfunc call: referenced arg needs refcounted PTR_TO_BTF_ID",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_kfunc_btf_id = {
		{ "bpf_kfunc_call_test_acquire", 3 },
		{ "bpf_kfunc_call_test_ref", 8 },
		{ "bpf_kfunc_call_test_release", 10 },
	},
	.result_unpriv = REJECT,
	.result = ACCEPT,
},
{
	"calls: invalid kfunc call: must provide (attach_prog_fd, btf_id) pair when freplace",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_EXT,
	.result = REJECT,
	.errstr = "Tracing programs must provide btf_id",
	.fixup_kfunc_btf_id = {
		{ "bpf_dynptr_from_skb", 0 },
	},
},
{
	"calls: basic sanity",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 2),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.result = ACCEPT,
},
{
	"calls: not on unprivileged",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 2),
	BPF_EXIT_INSN(),
	},
	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
	.result_unpriv = REJECT,
	.result = ACCEPT,
	.retval = 1,
},
{
	"calls: div by 0 in subprog",
	.insns = {
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV32_IMM(BPF_REG_2, 0),
	BPF_MOV32_IMM(BPF_REG_3, 1),
	BPF_ALU32_REG(BPF_DIV, BPF_REG_3, BPF_REG_2),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = ACCEPT,
	.retval = 1,
},
{
	"calls: multiple ret types in subprog 1",
	.insns = {
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_MOV32_IMM(BPF_REG_0, 42),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = REJECT,
	.errstr = "R0 invalid mem access 'scalar'",
},
{
	"calls: multiple ret types in subprog 2",
	.insns = {
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 9),
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6,
		    offsetof(struct __sk_buff, data)),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_map_hash_8b = { 16 },
	.result = REJECT,
	.errstr = "R0 min value is outside of the allowed memory range",
},
{
	"calls: overlapping caller/callee",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "last insn is not an exit or jmp",
	.result = REJECT,
},
{
	"calls: wrong recursive calls",
	.insns = {
	BPF_JMP_IMM(BPF_JA, 0, 0, 4),
	BPF_JMP_IMM(BPF_JA, 0, 0, 4),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -2),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "jump out of range",
	.result = REJECT,
},
{
	"calls: wrong src reg",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 3, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "BPF_CALL uses reserved fields",
	.result = REJECT,
},
{
	"calls: wrong off value",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, -1, 2),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 2),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "BPF_CALL uses reserved fields",
	.result = REJECT,
},
{
	"calls: jump back loop",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "the call stack of 9 frames is too deep",
	.result = REJECT,
},
{
	"calls: conditional call",
	.insns = {
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, mark)),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 2),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "jump out of range",
	.result = REJECT,
},
{
	"calls: conditional call 2",
	.insns = {
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, mark)),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 2),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 3),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.result = ACCEPT,
},
{
	"calls: conditional call 3",
	.insns = {
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, mark)),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
	BPF_JMP_IMM(BPF_JA, 0, 0, 4),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_JMP_IMM(BPF_JA, 0, 0, -6),
	BPF_MOV64_IMM(BPF_REG_0, 3),
	BPF_JMP_IMM(BPF_JA, 0, 0, -6),
	},
	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
	.errstr_unpriv = "back-edge from insn",
	.result_unpriv = REJECT,
	.result = ACCEPT,
	.retval = 1,
},
{
	"calls: conditional call 4",
	.insns = {
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, mark)),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_JMP_IMM(BPF_JA, 0, 0, -5),
	BPF_MOV64_IMM(BPF_REG_0, 3),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.result = ACCEPT,
},
{
	"calls: conditional call 5",
	.insns = {
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, mark)),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_JMP_IMM(BPF_JA, 0, 0, -6),
	BPF_MOV64_IMM(BPF_REG_0, 3),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = ACCEPT,
	.retval = 1,
},
{
	"calls: conditional call 6",
	.insns = {
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
	BPF_EXIT_INSN(),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, mark)),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.errstr = "infinite loop detected",
	.result = REJECT,
},
{
	"calls: using r0 returned by callee",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 2),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.result = ACCEPT,
},
{
	"calls: using uninit r0 from callee",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "!read_ok",
	.result = REJECT,
},
{
	"calls: callee is using r1",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, len)),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_ACT,
	.result = ACCEPT,
	.retval = TEST_DATA_LEN,
},
{
	"calls: callee using args1",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
	BPF_EXIT_INSN(),
	},
	.errstr_unpriv = "allowed for",
	.result_unpriv = REJECT,
	.result = ACCEPT,
	.retval = POINTER_VALUE,
},
{
	"calls: callee using wrong args2",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "R2 !read_ok",
	.result = REJECT,
},
{
	"calls: callee using two args",
	.insns = {
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
		    offsetof(struct __sk_buff, len)),
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6,
		    offsetof(struct __sk_buff, len)),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
	BPF_EXIT_INSN(),
	},
	.errstr_unpriv = "allowed for",
	.result_unpriv = REJECT,
	.result = ACCEPT,
	.retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
},
{
	"calls: callee changing pkt pointers",
	.insns = {
	BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, offsetof(struct xdp_md, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
		    offsetof(struct xdp_md, data_end)),
	BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8),
	BPF_JMP_REG(BPF_JGT, BPF_REG_8, BPF_REG_7, 2),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	/* clear_all_pkt_pointers() has to walk all frames
	 * to make sure that pkt pointers in the caller
	 * are cleared when callee is calling a helper that
	 * adjusts packet size
	 */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
	BPF_MOV32_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_2, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_xdp_adjust_head),
	BPF_EXIT_INSN(),
	},
	.result = REJECT,
	.errstr = "R6 invalid mem access 'scalar'",
	.prog_type = BPF_PROG_TYPE_XDP,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: ptr null check in subprog",
	.insns = {
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(),
	},
	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
	.fixup_map_hash_48b = { 3 },
	.result_unpriv = REJECT,
	.result = ACCEPT,
	.retval = 0,
},
{
	"calls: two calls with args",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
	BPF_EXIT_INSN(),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, len)),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = ACCEPT,
	.retval = TEST_DATA_LEN + TEST_DATA_LEN,
},
{
	"calls: calls with stack arith",
	.insns = {
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
	BPF_MOV64_IMM(BPF_REG_0, 42),
	BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = ACCEPT,
	.retval = 42,
},
{
	"calls: calls with misaligned stack access",
	.insns = {
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -61),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -63),
	BPF_MOV64_IMM(BPF_REG_0, 42),
	BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.flags = F_LOAD_WITH_STRICT_ALIGNMENT,
	.errstr = "misaligned stack access",
	.result = REJECT,
},
{
	"calls: calls control flow, jump test",
	.insns = {
	BPF_MOV64_IMM(BPF_REG_0, 42),
	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 43),
	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
	BPF_JMP_IMM(BPF_JA, 0, 0, -3),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = ACCEPT,
	.retval = 43,
},
{
	"calls: calls control flow, jump test 2",
	.insns = {
	BPF_MOV64_IMM(BPF_REG_0, 42),
	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 43),
	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.errstr = "jump out of range from insn 1 to 4",
	.result = REJECT,
},
{
	"calls: two calls with bad jump",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
	BPF_EXIT_INSN(),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, len)),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -3),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "jump out of range from insn 11 to 9",
	.result = REJECT,
},
{
	"calls: recursive call. test1",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -1),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "the call stack of 9 frames is too deep",
	.result = REJECT,
},
{
	"calls: recursive call. test2",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -3),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "the call stack of 9 frames is too deep",
	.result = REJECT,
},
{
	"calls: unreachable code",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "unreachable insn 6",
	.result = REJECT,
},
{
	"calls: invalid call",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, -4),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "invalid destination",
	.result = REJECT,
},
{
	"calls: invalid call 2",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 0x7fffffff),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "invalid destination",
	.result = REJECT,
},
{
	"calls: jumping across function bodies. test1",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -3),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "jump out of range",
	.result = REJECT,
},
{
	"calls: jumping across function bodies. test2",
	.insns = {
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "jump out of range",
	.result = REJECT,
},
{
	"calls: call without exit",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, -2),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "not an exit",
	.result = REJECT,
},
{
	"calls: call into middle of ld_imm64",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_LD_IMM64(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "last insn",
	.result = REJECT,
},
{
	"calls: call into middle of other call",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "last insn",
	.result = REJECT,
},
{
	"calls: subprog call with ld_abs in main prog",
	.insns = {
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_LD_ABS(BPF_B, 0),
	BPF_LD_ABS(BPF_H, 0),
	BPF_LD_ABS(BPF_W, 0),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_6),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
	BPF_LD_ABS(BPF_B, 0),
	BPF_LD_ABS(BPF_H, 0),
	BPF_LD_ABS(BPF_W, 0),
	BPF_EXIT_INSN(),
	BPF_MOV64_IMM(BPF_REG_2, 1),
	BPF_MOV64_IMM(BPF_REG_3, 2),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_skb_vlan_push),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = ACCEPT,
},
{
	"calls: two calls with bad fallthrough",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_0),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
		    offsetof(struct __sk_buff, len)),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
	.errstr = "not an exit",
	.result = REJECT,
},
{
	"calls: two calls with stack read",
	.insns = {
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 6),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
	BPF_EXIT_INSN(),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.result = ACCEPT,
},
{
	"calls: two calls with stack write",
	.insns = {
	/* main prog */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 7),
	BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
	/* write into stack frame of main prog */
	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
	BPF_EXIT_INSN(),

	/* subprog 2 */
	/* read from stack frame of main prog */
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.result = ACCEPT,
},
{
	"calls: stack overflow using two frames (pre-call access)",
	.insns = {
	/* prog 1 */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),

	/* prog 2 */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.errstr = "combined stack size",
	.result = REJECT,
},
{
	"calls: stack overflow using two frames (post-call access)",
	.insns = {
	/* prog 1 */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2),
	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
	BPF_EXIT_INSN(),

	/* prog 2 */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.errstr = "combined stack size",
	.result = REJECT,
},
{
	"calls: stack depth check using three frames. test1",
	.insns = {
	/* main */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	/* A */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
	BPF_EXIT_INSN(),
	/* B */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	/* stack_main=32, stack_A=256, stack_B=64
	 * and max(main+A, main+A+B) < 512
	 */
	.result = ACCEPT,
},
{
	"calls: stack depth check using three frames. test2",
	.insns = {
	/* main */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 5), /* call B */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -32, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	/* A */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
	BPF_EXIT_INSN(),
	/* B */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -3), /* call A */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	/* stack_main=32, stack_A=64, stack_B=256
	 * and max(main+A, main+A+B) < 512
	 */
	.result = ACCEPT,
},
{
	"calls: stack depth check using three frames. test3",
	.insns = {
	/* main */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 8), /* call B */
	BPF_JMP_IMM(BPF_JGE, BPF_REG_6, 0, 1),
	BPF_ST_MEM(BPF_B, BPF_REG_10, -64, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	/* A */
	BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 10, 1),
	BPF_EXIT_INSN(),
	BPF_ST_MEM(BPF_B, BPF_REG_10, -224, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, -3),
	/* B */
	BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 1),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, -6), /* call A */
	BPF_ST_MEM(BPF_B, BPF_REG_10, -256, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	/* stack_main=64, stack_A=224, stack_B=256
	 * and max(main+A, main+A+B) > 512
	 */
	.errstr = "combined stack",
	.result = REJECT,
},
{
	"calls: stack depth check using three frames. test4",
	/* void main(void) {
	 *   func1(0);
	 *   func1(1);
	 *   func2(1);
	 * }
	 * void func1(int alloc_or_recurse) {
	 *   if (alloc_or_recurse) {
	 *     frame_pointer[-300] = 1;
	 *   } else {
	 *     func2(alloc_or_recurse);
	 *   }
	 * }
	 * void func2(int alloc_or_recurse) {
	 *   if (alloc_or_recurse) {
	 *     frame_pointer[-300] = 1;
	 *   }
	 * }
	 */
	.insns = {
	/* main */
	BPF_MOV64_IMM(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 6), /* call A */
	BPF_MOV64_IMM(BPF_REG_1, 1),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 4), /* call A */
	BPF_MOV64_IMM(BPF_REG_1, 1),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 7), /* call B */
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	/* A */
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 2),
	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
	BPF_EXIT_INSN(),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
	BPF_EXIT_INSN(),
	/* B */
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
	BPF_ST_MEM(BPF_B, BPF_REG_10, -300, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.result = REJECT,
	.errstr = "combined stack",
},
{
	"calls: stack depth check using three frames. test5",
	.insns = {
	/* main */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
	BPF_EXIT_INSN(),
	/* A */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call B */
	BPF_EXIT_INSN(),
	/* B */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
	BPF_EXIT_INSN(),
	/* C */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
	BPF_EXIT_INSN(),
	/* D */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
	BPF_EXIT_INSN(),
	/* E */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
	BPF_EXIT_INSN(),
	/* F */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
	BPF_EXIT_INSN(),
	/* G */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
	BPF_EXIT_INSN(),
	/* H */
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.errstr = "call stack",
	.result = REJECT,
},
{
	"calls: stack depth check in dead code",
	.insns = {
	/* main */
	BPF_MOV64_IMM(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call A */
	BPF_EXIT_INSN(),
	/* A */
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 2), /* call B */
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	/* B */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call C */
	BPF_EXIT_INSN(),
	/* C */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call D */
	BPF_EXIT_INSN(),
	/* D */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call E */
	BPF_EXIT_INSN(),
	/* E */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call F */
	BPF_EXIT_INSN(),
	/* F */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call G */
	BPF_EXIT_INSN(),
	/* G */
	BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 1, 0, 1), /* call H */
	BPF_EXIT_INSN(),
	/* H */
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.errstr = "call stack",
	.result = REJECT,
},
{
	"calls: spill into caller stack frame",
	.insns = {
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),
	BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.errstr = "cannot spill",
	.result = REJECT,
},
{
	"calls: write into caller stack frame",
	.insns = {
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
	BPF_EXIT_INSN(),
	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.result = ACCEPT,
	.retval = 42,
},
{
	"calls: write into callee stack frame",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, -8),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.errstr = "cannot return stack pointer",
	.result = REJECT,
},
{
	"calls: two calls with stack write and void return",
	.insns = {
	/* main prog */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),

	/* subprog 2 */
	/* write into stack frame of main prog */
	BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
	BPF_EXIT_INSN(), /* void return */
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.result = ACCEPT,
},
{
	"calls: ambiguous return value",
	.insns = {
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_EXIT_INSN(),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.errstr_unpriv = "allowed for",
	.result_unpriv = REJECT,
	.errstr = "R0 !read_ok",
	.result = REJECT,
},
{
	"calls: two calls that return map_value",
	.insns = {
	/* main prog */
	/* pass fp-16, fp-8 into a function */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),

	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
	/* fetch secound map_value_ptr from the stack */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -16),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	/* call 3rd function twice */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	/* first time with fp-8 */
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
	/* second time with fp-16 */
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),

	/* subprog 2 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	/* lookup from map */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	/* write map_value_ptr into stack frame of main prog */
	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(), /* return 0 */
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.fixup_map_hash_8b = { 23 },
	.result = ACCEPT,
},
{
	"calls: two calls that return map_value with bool condition",
	.insns = {
	/* main prog */
	/* pass fp-16, fp-8 into a function */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	/* call 3rd function twice */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	/* first time with fp-8 */
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
	/* second time with fp-16 */
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
	/* fetch secound map_value_ptr from the stack */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
	BPF_EXIT_INSN(),

	/* subprog 2 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	/* lookup from map */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(), /* return 0 */
	/* write map_value_ptr into stack frame of main prog */
	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(), /* return 1 */
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.fixup_map_hash_8b = { 23 },
	.result = ACCEPT,
},
{
	"calls: two calls that return map_value with incorrect bool check",
	.insns = {
	/* main prog */
	/* pass fp-16, fp-8 into a function */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	/* call 3rd function twice */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	/* first time with fp-8 */
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 9),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
	/* second time with fp-16 */
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	/* fetch secound map_value_ptr from the stack */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
	BPF_EXIT_INSN(),

	/* subprog 2 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	/* lookup from map */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(), /* return 0 */
	/* write map_value_ptr into stack frame of main prog */
	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_0, 1),
	BPF_EXIT_INSN(), /* return 1 */
	},
	.prog_type = BPF_PROG_TYPE_XDP,
	.fixup_map_hash_8b = { 23 },
	.result = REJECT,
	.errstr = "R0 invalid mem access 'scalar'",
	.result_unpriv = REJECT,
	.errstr_unpriv = "invalid read from stack R7 off=-16 size=8",
},
{
	"calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1",
	.insns = {
	/* main prog */
	/* pass fp-16, fp-8 into a function */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	/* 1st lookup from map */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_8, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
	/* write map_value_ptr into stack frame of main prog at fp-8 */
	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_8, 1),

	/* 2nd lookup from map */
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
		     BPF_FUNC_map_lookup_elem),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_9, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
	/* write map_value_ptr into stack frame of main prog at fp-16 */
	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_9, 1),

	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),  /* 34 */
	BPF_EXIT_INSN(),

	/* subprog 2 */
	/* if arg2 == 1 do *arg1 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),

	/* if arg4 == 1 do *arg3 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_map_hash_8b = { 12, 22 },
	.result = REJECT,
	.errstr = "invalid access to map value, value_size=8 off=2 size=8",
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2",
	.insns = {
	/* main prog */
	/* pass fp-16, fp-8 into a function */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	/* 1st lookup from map */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_8, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
	/* write map_value_ptr into stack frame of main prog at fp-8 */
	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_8, 1),

	/* 2nd lookup from map */
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* 20 */
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, /* 24 */
		     BPF_FUNC_map_lookup_elem),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_9, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
	/* write map_value_ptr into stack frame of main prog at fp-16 */
	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_9, 1),

	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), /* 30 */
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),  /* 34 */
	BPF_EXIT_INSN(),

	/* subprog 2 */
	/* if arg2 == 1 do *arg1 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),

	/* if arg4 == 1 do *arg3 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_map_hash_8b = { 12, 22 },
	.result = ACCEPT,
},
{
	"calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3",
	.insns = {
	/* main prog */
	/* pass fp-16, fp-8 into a function */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	/* 1st lookup from map */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -24, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_8, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
	/* write map_value_ptr into stack frame of main prog at fp-8 */
	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_8, 1),

	/* 2nd lookup from map */
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -24),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_9, 0),  // 26
	BPF_JMP_IMM(BPF_JA, 0, 0, 2),
	/* write map_value_ptr into stack frame of main prog at fp-16 */
	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
	BPF_MOV64_IMM(BPF_REG_9, 1),

	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), // 30
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), // 34
	BPF_JMP_IMM(BPF_JA, 0, 0, -30),

	/* subprog 2 */
	/* if arg2 == 1 do *arg1 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),

	/* if arg4 == 1 do *arg3 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, -8),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_map_hash_8b = { 12, 22 },
	.result = REJECT,
	.errstr = "invalid access to map value, value_size=8 off=2 size=8",
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: two calls that receive map_value_ptr_or_null via arg. test1",
	.insns = {
	/* main prog */
	/* pass fp-16, fp-8 into a function */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	/* 1st lookup from map */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_8, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
	BPF_MOV64_IMM(BPF_REG_8, 1),

	/* 2nd lookup from map */
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_9, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
	BPF_MOV64_IMM(BPF_REG_9, 1),

	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),

	/* subprog 2 */
	/* if arg2 == 1 do *arg1 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),

	/* if arg4 == 1 do *arg3 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_map_hash_8b = { 12, 22 },
	.result = ACCEPT,
},
{
	"calls: two calls that receive map_value_ptr_or_null via arg. test2",
	.insns = {
	/* main prog */
	/* pass fp-16, fp-8 into a function */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_2),
	/* 1st lookup from map */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_8, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
	BPF_MOV64_IMM(BPF_REG_8, 1),

	/* 2nd lookup from map */
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
	BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
	BPF_MOV64_IMM(BPF_REG_9, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
	BPF_MOV64_IMM(BPF_REG_9, 1),

	/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_8),
	BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_9),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),

	/* subprog 2 */
	/* if arg2 == 1 do *arg1 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 1, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),

	/* if arg4 == 0 do *arg3 = 0 */
	BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, 2),
	/* fetch map_value_ptr from the stack of this function */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
	/* write into map value */
	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.fixup_map_hash_8b = { 12, 22 },
	.result = REJECT,
	.errstr = "R0 invalid mem access 'scalar'",
},
{
	"calls: pkt_ptr spill into caller stack",
	.insns = {
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	/* spill unchecked pkt_ptr into stack of caller */
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
	/* now the pkt range is verified, read pkt_ptr from stack */
	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
	/* write 4 bytes into packet */
	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
	BPF_EXIT_INSN(),
	},
	.result = ACCEPT,
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.retval = POINTER_VALUE,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: pkt_ptr spill into caller stack 2",
	.insns = {
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	/* Marking is still kept, but not in all cases safe. */
	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
	BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	/* spill unchecked pkt_ptr into stack of caller */
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
	/* now the pkt range is verified, read pkt_ptr from stack */
	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
	/* write 4 bytes into packet */
	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.errstr = "invalid access to packet",
	.result = REJECT,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: pkt_ptr spill into caller stack 3",
	.insns = {
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
	/* Marking is still kept and safe here. */
	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
	BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	/* spill unchecked pkt_ptr into stack of caller */
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_MOV64_IMM(BPF_REG_5, 0),
	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
	BPF_MOV64_IMM(BPF_REG_5, 1),
	/* now the pkt range is verified, read pkt_ptr from stack */
	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0),
	/* write 4 bytes into packet */
	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = ACCEPT,
	.retval = 1,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: pkt_ptr spill into caller stack 4",
	.insns = {
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
	/* Check marking propagated. */
	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
	BPF_ST_MEM(BPF_W, BPF_REG_4, 0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	/* spill unchecked pkt_ptr into stack of caller */
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_MOV64_IMM(BPF_REG_5, 0),
	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
	BPF_MOV64_IMM(BPF_REG_5, 1),
	/* don't read back pkt_ptr from stack here */
	/* write 4 bytes into packet */
	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = ACCEPT,
	.retval = 1,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: pkt_ptr spill into caller stack 5",
	.insns = {
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	BPF_MOV64_IMM(BPF_REG_5, 0),
	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
	/* spill checked pkt_ptr into stack of caller */
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_MOV64_IMM(BPF_REG_5, 1),
	/* don't read back pkt_ptr from stack here */
	/* write 4 bytes into packet */
	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.errstr = "same insn cannot be used with different",
	.result = REJECT,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: pkt_ptr spill into caller stack 6",
	.insns = {
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	BPF_MOV64_IMM(BPF_REG_5, 0),
	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
	/* spill checked pkt_ptr into stack of caller */
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_MOV64_IMM(BPF_REG_5, 1),
	/* don't read back pkt_ptr from stack here */
	/* write 4 bytes into packet */
	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.errstr = "R4 invalid mem access",
	.result = REJECT,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: pkt_ptr spill into caller stack 7",
	.insns = {
	BPF_MOV64_IMM(BPF_REG_2, 0),
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	BPF_MOV64_IMM(BPF_REG_5, 0),
	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
	/* spill checked pkt_ptr into stack of caller */
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_MOV64_IMM(BPF_REG_5, 1),
	/* don't read back pkt_ptr from stack here */
	/* write 4 bytes into packet */
	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.errstr = "R4 invalid mem access",
	.result = REJECT,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: pkt_ptr spill into caller stack 8",
	.insns = {
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	BPF_MOV64_IMM(BPF_REG_5, 0),
	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 3),
	/* spill checked pkt_ptr into stack of caller */
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_MOV64_IMM(BPF_REG_5, 1),
	/* don't read back pkt_ptr from stack here */
	/* write 4 bytes into packet */
	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.result = ACCEPT,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: pkt_ptr spill into caller stack 9",
	.insns = {
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
	BPF_EXIT_INSN(),
	BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_4, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
		    offsetof(struct __sk_buff, data)),
	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
		    offsetof(struct __sk_buff, data_end)),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
	BPF_MOV64_IMM(BPF_REG_5, 0),
	/* spill unchecked pkt_ptr into stack of caller */
	BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0),
	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 2),
	BPF_MOV64_IMM(BPF_REG_5, 1),
	/* don't read back pkt_ptr from stack here */
	/* write 4 bytes into packet */
	BPF_ST_MEM(BPF_W, BPF_REG_2, 0, 0),
	BPF_MOV64_REG(BPF_REG_0, BPF_REG_5),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
	.errstr = "invalid access to packet",
	.result = REJECT,
	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
},
{
	"calls: caller stack init to zero or map_value_or_null",
	.insns = {
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	/* fetch map_value_or_null or const_zero from stack */
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
	/* store into map_value */
	BPF_ST_MEM(BPF_W, BPF_REG_0, 0, 0),
	BPF_EXIT_INSN(),

	/* subprog 1 */
	/* if (ctx == 0) return; */
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 8),
	/* else bpf_map_lookup() and *(fp - 8) = r0 */
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
	BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.fixup_map_hash_8b = { 13 },
	.result = ACCEPT,
	.prog_type = BPF_PROG_TYPE_XDP,
},
{
	"calls: stack init to zero and pruning",
	.insns = {
	/* first make allocated_stack 16 byte */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
	/* now fork the execution such that the false branch
	 * of JGT insn will be verified second and it skisp zero
	 * init of fp-8 stack slot. If stack liveness marking
	 * is missing live_read marks from call map_lookup
	 * processing then pruning will incorrectly assume
	 * that fp-8 stack slot was unused in the fall-through
	 * branch and will accept the program incorrectly
	 */
	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
	BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 2, 2),
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	BPF_JMP_IMM(BPF_JA, 0, 0, 0),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1, 0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.fixup_map_hash_48b = { 7 },
	.errstr_unpriv = "invalid indirect read from stack R2 off -8+0 size 8",
	.result_unpriv = REJECT,
	/* in privileged mode reads from uninitialized stack locations are permitted */
	.result = ACCEPT,
},
{
	"calls: ctx read at start of subprog",
	.insns = {
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
	BPF_JMP_REG(BPF_JSGT, BPF_REG_0, BPF_REG_0, 0),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_EXIT_INSN(),
	BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
	.result_unpriv = REJECT,
	.result = ACCEPT,
},
{
	"calls: cross frame pruning",
	.insns = {
	/* r8 = !!random();
	 * call pruner()
	 * if (r8)
	 *     do something bad;
	 */
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
	BPF_MOV64_IMM(BPF_REG_8, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_MOV64_IMM(BPF_REG_8, 1),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1),
	BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
	.errstr = "!read_ok",
	.result = REJECT,
},
{
	"calls: cross frame pruning - liveness propagation",
	.insns = {
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
	BPF_MOV64_IMM(BPF_REG_8, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_MOV64_IMM(BPF_REG_8, 1),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
	BPF_MOV64_IMM(BPF_REG_9, 0),
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
	BPF_MOV64_IMM(BPF_REG_9, 1),
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1),
	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0),
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
	BPF_EXIT_INSN(),
	},
	.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
	.errstr_unpriv = "loading/calling other bpf or kernel functions are allowed for",
	.errstr = "!read_ok",
	.result = REJECT,
},
/* Make sure that verifier.c:states_equal() considers IDs from all
 * frames when building 'idmap' for check_ids().
 */
{
	"calls: check_ids() across call boundary",
	.insns = {
	/* Function main() */
	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
	/* fp[-24] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1,
		      0),
	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
	BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -24),
	/* fp[-32] = map_lookup_elem(...) ; get a MAP_VALUE_PTR_OR_NULL with some ID */
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
	BPF_LD_MAP_FD(BPF_REG_1,
		      0),
	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
	BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_0, -32),
	/* call foo(&fp[-24], &fp[-32])   ; both arguments have IDs in the current
	 *                                ; stack frame
	 */
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -24),
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP),
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -32),
	BPF_CALL_REL(2),
	/* exit 0 */
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	/* Function foo()
	 *
	 * r9 = &frame[0].fp[-24]  ; save arguments in the callee saved registers,
	 * r8 = &frame[0].fp[-32]  ; arguments are pointers to pointers to map value
	 */
	BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
	BPF_MOV64_REG(BPF_REG_8, BPF_REG_2),
	/* r7 = ktime_get_ns() */
	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
	/* r6 = ktime_get_ns() */
	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
	/* if r6 > r7 goto +1      ; no new information about the state is derived from
	 *                         ; this check, thus produced verifier states differ
	 *                         ; only in 'insn_idx'
	 * r9 = r8
	 */
	BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 1),
	BPF_MOV64_REG(BPF_REG_9, BPF_REG_8),
	/* r9 = *r9                ; verifier get's to this point via two paths:
	 *                         ; (I) one including r9 = r8, verified first;
	 *                         ; (II) one excluding r9 = r8, verified next.
	 *                         ; After load of *r9 to r9 the frame[0].fp[-24].id == r9.id.
	 *                         ; Suppose that checkpoint is created here via path (I).
	 *                         ; When verifying via (II) the r9.id must be compared against
	 *                         ; frame[0].fp[-24].id, otherwise (I) and (II) would be
	 *                         ; incorrectly deemed equivalent.
	 * if r9 == 0 goto <exit>
	 */
	BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_9, 0),
	BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 0, 1),
	/* r8 = *r8                ; read map value via r8, this is not safe
	 * r0 = *r8                ; because r8 might be not equal to r9.
	 */
	BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_8, 0),
	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_8, 0),
	/* exit 0 */
	BPF_MOV64_IMM(BPF_REG_0, 0),
	BPF_EXIT_INSN(),
	},
	.flags = BPF_F_TEST_STATE_FREQ,
	.fixup_map_hash_8b = { 3, 9 },
	.result = REJECT,
	.errstr = "R8 invalid mem access 'map_value_or_null'",
	.result_unpriv = REJECT,
	.errstr_unpriv = "",
	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
},