@@ -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,
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(-)