diff options
author | mjacob <mjacob@FreeBSD.org> | 2001-10-18 17:26:52 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2001-10-18 17:26:52 +0000 |
commit | d2eb759e62a8874cdd63db53ddc6b5f50c210497 (patch) | |
tree | e640786dae01d956fa77510748ce907637d97b3b | |
parent | 89037ce3ad84f3d5a9e4d9a106de67608519125e (diff) | |
download | FreeBSD-src-d2eb759e62a8874cdd63db53ddc6b5f50c210497.zip FreeBSD-src-d2eb759e62a8874cdd63db53ddc6b5f50c210497.tar.gz |
Protect against deranged fabric nameservers that spit out 10000 identical
port numbers.
MFC after: 1 day
-rw-r--r-- | sys/dev/isp/isp.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 66518e2..db6c275 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -2263,11 +2263,11 @@ static int isp_scan_fabric(struct ispsoftc *isp) { fcparam *fcp = isp->isp_param; - u_int32_t portid, first_portid; + u_int32_t portid, first_portid, last_portid; sns_screq_t *reqp; sns_scrsp_t *resp; mbreg_t mbs; - int hicap, first_portid_seen; + int hicap, first_portid_seen, last_port_same; if (fcp->isp_onfabric == 0) { fcp->isp_loopstate = LOOP_FSCAN_DONE; @@ -2280,6 +2280,8 @@ isp_scan_fabric(struct ispsoftc *isp) * Since Port IDs are 24 bits, we can check against having seen * anything yet with this value. */ + last_port_same = 0; + last_portid = 0xffffffff; /* not a port */ first_portid = portid = fcp->isp_portid; fcp->isp_loopstate = LOOP_SCANNING_FABRIC; @@ -2358,9 +2360,20 @@ isp_scan_fabric(struct ispsoftc *isp) fcp->isp_loopstate = LOOP_FSCAN_DONE; return (0); } + if (portid == last_portid) { + if (last_port_same++ > 20) { + isp_prt(isp, ISP_LOGWARN, + "tangled fabric database detected"); + break; + } + } else { + last_portid = portid; + } } - isp_prt(isp, ISP_LOGWARN, "broken fabric nameserver...*wheeze*..."); + if (hicap >= 65535) { + isp_prt(isp, ISP_LOGWARN, "fabric too big (> 65535)"); + } /* * We either have a broken name server or a huge fabric if we get here. |