From f3d2847dd0050b474e2bb37b6a1d1cb771e2b258 Mon Sep 17 00:00:00 2001 From: Hidetoshi Shimokawa Date: Fri, 14 Feb 2003 03:09:59 +0000 Subject: - Though I got a feedback from the originator of kern/48129 that the previous revision fixed the panic, I found the problem exits in another part of the function by investigating the crom dump sent by him. The search was started in the middle of bus info block and the routine misunderstood the EUI64 as a crom entry. This problem is fixed. PR: kern/48129 Fix incorrect type mask included in a logical unit number and check the validity of the lun. --- sys/dev/firewire/sbp.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'sys/dev') diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c index 079ea742c1f6c..f8bc93b77ff17 100644 --- a/sys/dev/firewire/sbp.c +++ b/sys/dev/firewire/sbp.c @@ -474,7 +474,7 @@ END_DEBUG reg = crom_search_key(&cc, CROM_LUN); if (reg == NULL) break; - lun = reg->val & 0xff; + lun = reg->val & 0xffff; SBP_DEBUG(0) printf("target %d lun %d found\n", target->target_id, lun); END_DEBUG @@ -482,10 +482,11 @@ END_DEBUG maxlun = lun; crom_next(&cc); } - target->num_lun = maxlun + 1; - if (maxlun < 0) { + if (maxlun < 0) printf("no lun found!\n"); - } + if (maxlun >= SBP_NUM_LUNS) + maxlun = SBP_NUM_LUNS; + target->num_lun = maxlun + 1; target->luns = (struct sbp_dev *) malloc( sizeof(struct sbp_dev) * target->num_lun, M_SBP, M_NOWAIT | M_ZERO); @@ -501,13 +502,17 @@ END_DEBUG reg = crom_search_key(&cc, CROM_LUN); if (reg == NULL) break; - lun = reg->val & 0xff; + lun = reg->val & 0xffff; + if (lun >= SBP_NUM_LUNS) { + printf("too large lun %d\n", lun); + continue; + } target->luns[lun].status = SBP_DEV_RESET; - target->luns[lun].type = (reg->val & 0x0f00) >> 16; + target->luns[lun].type = (reg->val & 0xf0000) >> 16; crom_next(&cc); - } - return target; -} + } + return target; + } static void sbp_get_text_leaf(struct fw_device *fwdev, int key, char *buf, int len) @@ -519,9 +524,10 @@ sbp_get_text_leaf(struct fw_device *fwdev, int key, char *buf, int len) u_int32_t *src, *dst; chdr = (struct csrhdr *)&fwdev->csrrom[0]; - creg = (struct csrreg *)chdr; - creg += chdr->info_len; - for( i = chdr->info_len + 4; i <= fwdev->rommax - 4; i+=4){ + /* skip crom header, bus info and root directory */ + creg = (struct csrreg *)chdr + chdr->info_len + 2; + /* search unitl the one before the last. */ + for (i = chdr->info_len + 2; i < fwdev->rommax / 4; i++) { if((creg++)->key == key){ found = 1; break; -- cgit v1.3