diff options
author | simokawa <simokawa@FreeBSD.org> | 2003-02-14 03:09:59 +0000 |
---|---|---|
committer | simokawa <simokawa@FreeBSD.org> | 2003-02-14 03:09:59 +0000 |
commit | ee568cc79e5011ade30e0ab18dc592ee3152cbca (patch) | |
tree | bbc98a7fc29be58f158a2ae39fc5d197eacaf219 /sys | |
parent | d8fb26b1c6097066a057362bdf7ad3d5e61c349b (diff) | |
download | FreeBSD-src-ee568cc79e5011ade30e0ab18dc592ee3152cbca.zip FreeBSD-src-ee568cc79e5011ade30e0ab18dc592ee3152cbca.tar.gz |
- 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.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/firewire/sbp.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c index 079ea74..f8bc93b 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; |