The bug is here: p->target_id, p->target_lun);
The list iterator 'p' will point to a bogus position containing HEAD if the list is empty or no element is found. This case must be checked before any use of the iterator, otherwise it will lead to a invalid memory access.
To fix this bug, add an check. Use a new variable 'iter' as the list iterator, while use the origin variable 'p' as a dedicated pointer to point to the found element.
Cc: stable@vger.kernel.org Fixes: ^1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com --- drivers/scsi/dc395x.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index c11916b8ae00..bbc03190a6f2 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -3588,10 +3588,19 @@ static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, #endif if (dcb->target_lun != 0) { /* Copy settings */ - struct DeviceCtlBlk *p; - list_for_each_entry(p, &acb->dcb_list, list) - if (p->target_id == dcb->target_id) + struct DeviceCtlBlk *p = NULL, *iter; + + list_for_each_entry(iter, &acb->dcb_list, list) + if (iter->target_id == dcb->target_id) { + p = iter; break; + } + + if (!p) { + kfree(dcb); + return NULL; + } + dprintkdbg(DBG_1, "device_alloc: <%02i-%i> copy from <%02i-%i>\n", dcb->target_id, dcb->target_lun,