Hello,
Patch fixes potential use-after-free in pf_table.c:pfr_set_addrs():
463 for (i = 0; i < size; i++) {
...
483 q = pfr_lookup_addr(tmpkt, &ad, 1);
484 if (q != NULL) {
485 ad.pfra_fback = PFR_FB_DUPLICATE;
486 goto _skip;
487 }
488 p = pfr_create_kentry(&ad);
489 if (p == NULL)
490 senderr(ENOMEM);
491 if (pfr_route_kentry(tmpkt, p)) {
492 pfr_destroy_kentry(p);
493 ad.pfra_fback = PFR_FB_NONE;
494 } else {
495 SLIST_INSERT_HEAD(&addq, p, pfrke_workq);
496 ad.pfra_fback = PFR_FB_ADDED;
497 xadd++;
498 }
499 if (p->pfrke_type == PFRKE_COST)
500 kt->pfrkt_refcntcost++;
501 pfr_ktable_winfo_update(kt, p);
502 }
503 _skip:
504 if (flags & PFR_FLAG_FEEDBACK)
505 if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
506 senderr(EFAULT);
507 }
the things start to go downhill if PF takes branch at 492, where `p` gets
freed. The code jumps to 499 & 501, where PF steps to dead pointer. I think the
right thing is to use goto _skip; in that branch to avoid 499 et. al.
completely.
path is below.
OK?
thanks and
regards
sasha
--------8<---------------8<---------------8<------------------8<--------
Index: pf_table.c
===================================================================
RCS file: /cvs/src/sys/net/pf_table.c,v
retrieving revision 1.115
diff -u -p -r1.115 pf_table.c
--- pf_table.c 7 Oct 2015 11:57:44 -0000 1.115
+++ pf_table.c 3 Nov 2015 20:15:26 -0000
@@ -491,6 +491,7 @@ pfr_set_addrs(struct pfr_table *tbl, str
if (pfr_route_kentry(tmpkt, p)) {
pfr_destroy_kentry(p);
ad.pfra_fback = PFR_FB_NONE;
+ goto _skip;
} else {
SLIST_INSERT_HEAD(&addq, p, pfrke_workq);
ad.pfra_fback = PFR_FB_ADDED;