SEC("?tc")
__failure __msg("arg#0 doesn't point to an irq flag on stack") int irq_save_bad_arg(struct __sk_buff *ctx)
{
bpf_local_irq_save(&global_flags); return0;
}
SEC("?tc")
__failure __msg("arg#0 doesn't point to an irq flag on stack") int irq_restore_bad_arg(struct __sk_buff *ctx)
{
bpf_local_irq_restore(&global_flags); return0;
}
SEC("?tc")
__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_local_irq_save-ed region") int irq_restore_missing_2(struct __sk_buff *ctx)
{ unsignedlong flags1; unsignedlong flags2;
SEC("?tc")
__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_local_irq_save-ed region") int irq_restore_missing_3(struct __sk_buff *ctx)
{ unsignedlong flags1; unsignedlong flags2; unsignedlong flags3;
SEC("?tc")
__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_local_irq_save-ed region") int irq_restore_missing_3_minus_2(struct __sk_buff *ctx)
{ unsignedlong flags1; unsignedlong flags2; unsignedlong flags3;
SEC("?tc")
__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_local_irq_save-ed region") int irq_restore_missing_1_subprog(struct __sk_buff *ctx)
{ unsignedlong flags;
local_irq_save(&flags); return0;
}
SEC("?tc")
__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_local_irq_save-ed region") int irq_restore_missing_2_subprog(struct __sk_buff *ctx)
{ unsignedlong flags1; unsignedlong flags2;
SEC("?tc")
__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_local_irq_save-ed region") int irq_restore_missing_3_subprog(struct __sk_buff *ctx)
{ unsignedlong flags1; unsignedlong flags2; unsignedlong flags3;
SEC("?tc")
__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_local_irq_save-ed region") int irq_restore_missing_3_minus_2_subprog(struct __sk_buff *ctx)
{ unsignedlong flags1; unsignedlong flags2; unsignedlong flags3;
SEC("?tc")
__failure __msg("cannot restore irq state out of order") int irq_restore_ooo(struct __sk_buff *ctx)
{ unsignedlong flags1; unsignedlong flags2;
SEC("?tc")
__failure __msg("cannot restore irq state out of order") int irq_restore_ooo_3(struct __sk_buff *ctx)
{ unsignedlong flags1; unsignedlong flags2; unsignedlong flags3;
SEC("?tc")
__failure __msg("cannot restore irq state out of order") int irq_restore_ooo_3_subprog(struct __sk_buff *ctx)
{ unsignedlong flags1; unsignedlong flags2; unsignedlong flags3;
/* Ensure same sized slot has st->ref_obj_id set, so we reject based on *slot_type!=STACK_IRQ_FLAG...
*/
_Static_assert(sizeof(it) == sizeof(unsignedlong), "broken iterator size");
SEC("?tc")
__failure __msg("cannot restore irq state out of order") int irq_ooo_refs_array(struct __sk_buff *ctx)
{ unsignedlong flags[4]; struct { int i; } *p;
/* refs=1 */
bpf_local_irq_save(&flags[0]);
/* refs=1,2 */
p = bpf_obj_new(typeof(*p)); if (!p) {
bpf_local_irq_restore(&flags[0]); return0;
}
/* refs=1,2,3 */
bpf_local_irq_save(&flags[1]);
/* refs=1,2,3,4 */
bpf_local_irq_save(&flags[2]);
/* Now when we remove ref=2, the verifier must not break the ordering in *therefsarraybetween1,3,4.Withanolderimplementation,the *verifierwouldswapthelastelementwiththeremovedelement,butto *maintainthestackpropertyweneedtousememmove.
*/
bpf_obj_drop(p);
/* Save and restore to reset active_irq_id to 3, as the ordering is now *refs=1,4,3.Whenrestoringthelinearscanwillfindprev_idinorder *as3insteadof4.
*/
bpf_local_irq_save(&flags[3]);
bpf_local_irq_restore(&flags[3]);
/* With the incorrect implementation, we can release flags[1], flags[2], *andflags[0],i.e.inthewrongorder.
*/
bpf_local_irq_restore(&flags[1]);
bpf_local_irq_restore(&flags[2]);
bpf_local_irq_restore(&flags[0]); return0;
}
int __noinline
global_subprog(int i)
{ if (i)
bpf_printk("%p", &i); return i;
}
int __noinline
global_sleepable_helper_subprog(int i)
{ if (i)
bpf_copy_from_user(&i, sizeof(i), NULL); return i;
}
int __noinline
global_sleepable_kfunc_subprog(int i)
{ if (i)
bpf_copy_from_user_str(&i, sizeof(i), NULL, 0);
global_subprog(i); return i;
}
int __noinline
global_subprog_calling_sleepable_global(int i)
{ if (!i)
global_sleepable_kfunc_subprog(i); return i;
}
SEC("?syscall")
__success int irq_non_sleepable_global_subprog(void *ctx)
{ unsignedlong flags;
SEC("?syscall")
__failure __msg("global functions that may sleep are not allowed in non-sleepable context") int irq_sleepable_helper_global_subprog(void *ctx)
{ unsignedlong flags;
SEC("?syscall")
__failure __msg("global functions that may sleep are not allowed in non-sleepable context") int irq_sleepable_global_subprog_indirect(void *ctx)
{ unsignedlong flags;
SEC("?tc")
__failure __msg("function calls are not allowed") int irq_wrong_kfunc_class_1(struct __sk_buff *ctx)
{ unsignedlong flags1;
if (bpf_res_spin_lock_irqsave(&lockA, &flags1)) return0; /* For now, bpf_local_irq_restore is not allowed in critical section, *butthistestensureserrorwillbecaughtwithkfunc_classwhenit's *openedup.Testedbytemporarilypermittingthiskfuncincritical *section.
*/
bpf_local_irq_restore(&flags1);
bpf_res_spin_unlock_irqrestore(&lockA, &flags1); return0;
}
SEC("?tc")
__failure __msg("function calls are not allowed") int irq_wrong_kfunc_class_2(struct __sk_buff *ctx)
{ unsignedlong flags1, flags2;
bpf_local_irq_save(&flags1); if (bpf_res_spin_lock_irqsave(&lockA, &flags2)) return0;
bpf_local_irq_restore(&flags2);
bpf_res_spin_unlock_irqrestore(&lockA, &flags1); return0;
}
char _license[] SEC("license") = "GPL";
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.12Bemerkung:
(vorverarbeitet am 2026-10-11)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.