DF-0603 / fix.diff
diff --git a/sys/net/pf/pf_if.c b/sys/net/pf/pf_if.c --- a/sys/net/pf/pf_if.c +++ b/sys/net/pf/pf_if.c @@ -772,10 +772,22 @@ if (pfi_skip_if(name, p)) continue; if (*size > n++) { + struct pfi_kif ucopy; if (!p->pfik_tzero) p->pfik_tzero = time_second; pfi_kif_ref(p, PFI_KIF_REF_RULE); - if (copyout(p, buf++, sizeof(*buf))) { + /* + * Never leak kernel pointers to userspace. Copy the + * kif to a stack scratch and explicitly zero every + * pointer field (RB_ENTRY linkage, ifp/group, and the + * dynaddr TAILQ_HEAD) before copyout(). + */ + ucopy = *p; + bzero(&ucopy.pfik_tree, sizeof(ucopy.pfik_tree)); + ucopy.pfik_ifp = NULL; + ucopy.pfik_group = NULL; + bzero(&ucopy.pfik_dynaddrs, sizeof(ucopy.pfik_dynaddrs)); + if (copyout(&ucopy, buf++, sizeof(ucopy))) { pfi_kif_unref(p, PFI_KIF_REF_RULE); crit_exit(); return (EFAULT); |