tests: deterministic runner (per-gate VM reset), hardened unload path

This commit is contained in:
lgcosta committed 2026-11-11 18:03:57 -03:00
1 parent a0941b77fe
commit 2690d6145c
12 files changed
+138 -60

No files matched your search

+2 -2
View File
@@ -313,12 +313,12 @@ struct pfk_rwlock {
#undef _IOWR
#define PFKXIOC_NRBITS 8
#define PFKXIOC_TYPEBITS 8
#define PFKXIOC_SIZEBITS 13
#define PFKXIOC_SIZEBITS 14
#define PFKXIOC_DIRBITS 2
#define PFKXIOC_NRSHIFT 0
#define PFKXIOC_TYPESHIFT (PFKXIOC_NRSHIFT + PFKXIOC_NRBITS)
#define PFKXIOC_SIZESHIFT (PFKXIOC_TYPESHIFT + PFKXIOC_TYPEBITS)
#define PFKXIOC_DIRSHIFT (PFKXIOC_SIZESHIFT + PFKXIOC_SIZEBITS + 1)
#define PFKXIOC_DIRSHIFT (PFKXIOC_SIZESHIFT + PFKXIOC_SIZEBITS)
#define PFKXIOC_NONE 0U
#define PFKXIOC_WRITE 1U /* OpenBSD IOC_IN (copyin) */
#define PFKXIOC_READ 2U /* OpenBSD IOC_OUT (copyout) */
+2
View File
@@ -5020,6 +5020,8 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
if (pd->virtual_proto != PF_VPROTO_FRAGMENT
&& !ctx.state_icmp && r->keep_state) {
pr_info_ratelimited("pfk: state-eligible proto=%d kstate=%d\n",
pd->proto, r->keep_state);
if (r->rule_flag & PFRULE_SRCTRACK &&
pf_insert_src_node(&ctx.sns[PF_SN_NONE], r, PF_SN_NONE,
+7 -2
View File
@@ -2266,35 +2266,40 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
sizeof(pr->anchor) ||
strnlen(pr->anchor_call, sizeof(pr->anchor_call)) >=
sizeof(pr->anchor_call)) {
error = ENAMETOOLONG;
error = ENAMETOOLONG; pr_info("pfkE: addrule1\n");
goto fail;
}
rule = pool_get(&pf_rule_pl, PR_WAITOK|PR_LIMITFAIL|PR_ZERO);
if (rule == NULL) {
error = ENOMEM;
error = ENOMEM; pr_info("pfkE: addrule-pool\n");
goto fail;
}
if ((error = pf_rule_copyin(&pr->rule, rule))) {
pr_info("pfkE: addrule copyin=%d\n", error);
pf_rule_free(rule);
rule = NULL;
goto fail;
}
if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
pr_info("pfkE: addrule icmp %x\n", pr->rule.return_icmp);
error = EINVAL;
pf_rule_free(rule);
rule = NULL;
goto fail;
}
if ((error = pf_rule_checkaf(rule))) {
pr_info("pfkE: addrule checkaf=%d\n", error);
pf_rule_free(rule);
rule = NULL;
goto fail;
}
if (rule->src.addr.type == PF_ADDR_NONE ||
rule->dst.addr.type == PF_ADDR_NONE) {
pr_info("pfkE: addrule none src=%d dst=%d\n",
rule->src.addr.type, rule->dst.addr.type);
error = EINVAL;
pf_rule_free(rule);
rule = NULL;
+14 -7
View File
@@ -33,18 +33,25 @@ struct pfk_pkt {
int dir;
};
#define PFK_MARK_PASSED 0x50460001u /* skb->mark: survived pf_test already */
#define PFK_DONE_IN 0x50460010u /* skb->mark bit: PF_IN pass completed */
#define PFK_DONE_OUT 0x50460020u /* skb->mark bit: PF_OUT pass completed */
static void
pfk_pkt_reinject(struct pfk_pkt *pk)
{
struct sk_buff *skb = pk->skb;
skb->mark = PFK_MARK_PASSED;
pk->skb->mark |= (pk->dir == PF_IN) ? PFK_DONE_IN : PFK_DONE_OUT;
if (pk->dir == PF_IN) {
if (skb->dev)
/* netif_rx expects data at the network header (eth_type_trans
* already done by the driver) — exactly the state the PRE
* hook sees. protocol/mac_header are preserved. */
if (skb->dev) {
skb_reset_network_header(skb);
skb->protocol = htons(pk->af == AF_INET ?
ETH_P_IP : ETH_P_IPV6);
netif_rx(skb);
else {
} else {
kfree_skb(skb);
}
} else {
@@ -123,11 +130,9 @@ pfk_enqueue_verdict(int af, struct sk_buff *skb,
{
struct pfk_pkt *pk;
struct pfk_ifnet *ifp;
unsigned int pk_dir_done __maybe_unused;
int dir;
if (skb->mark == PFK_MARK_PASSED)
return NF_ACCEPT;
switch (st->hook) {
case NF_INET_PRE_ROUTING:
dir = PF_IN;
@@ -139,6 +144,8 @@ pfk_enqueue_verdict(int af, struct sk_buff *skb,
default:
return NF_ACCEPT; /* LOCAL_IN/FORWARD */
}
if (skb->mark & (dir == PF_IN ? PFK_DONE_IN : PFK_DONE_OUT))
return NF_ACCEPT;
if (af == AF_INET && !pskb_may_pull(skb, sizeof(struct pf_ip)))
return NF_ACCEPT;
+16
View File
@@ -54,6 +54,9 @@ pfk_ioctl_io(struct file *filp, unsigned int cmd, unsigned long arg)
p.p_ucred = &cred;
p.p_p = &pp;
if (cmd == DIOCADDRULE)
pr_info("pfkE: ioctl sz=%d kern_size=%d rule=%d\n", (int)sz,
(int)sizeof(struct pfioc_rule), (int)sizeof(struct pf_rule));
kdata = kzalloc(sz ? sz : sizeof(long), GFP_KERNEL);
if (!kdata)
return -ENOMEM;
@@ -127,6 +130,7 @@ static int __init pfk_init(void)
* No NET_LOCK here: pfattach/pfi take what locks they need (PF_LOCK),
* and control ioctls serialize with NET_LOCK themselves. */
pf_status_init();
stoeplitz_init(); /* pf.c flow-id hashing cache (was never called) */
pfattach(0);
pfk_if_set_event_cb(pfk_pfi_event);
pfk_if_iterate(pfk_pfi_attach_one);
@@ -149,9 +153,21 @@ err_mbuf:
return err;
}
extern struct timeout pf_purge_to, pf_purge_states_to;
static void __exit pfk_exit(void)
{
/* stop sources before flushing workqueues: the purge timer
* self-rearms (pf_purge re-arms on every run) and would keep the
* workqueues non-empty forever (observed rmmod hang). */
misc_deregister(&pfk_dev);
pfk_net_lock();
pf_status.running = 0;
pfk_net_unlock();
timeout_del(&pf_purge_to);
timeout_del(&pf_purge_states_to);
timeout_del_sync(&pf_purge_to);
timeout_del_sync(&pf_purge_states_to);
pfk_hooks_unregister();
pfk_if_exit();
pfk_pcb_exit();