diff mbox series

scsi: aic7xxx: aic79xx: Add missing check in ahc_handle_seqint

Message ID 20210310105042.31660-1-dinghao.liu@zju.edu.cn (mailing list archive)
State Deferred
Headers show
Series scsi: aic7xxx: aic79xx: Add missing check in ahc_handle_seqint | expand

Commit Message

Dinghao Liu March 10, 2021, 10:50 a.m. UTC
ahc_lookup_scb() may return a null pointer and further lead to
null-pointer-dereference in case DATA_OVERRUN. Fix this by adding
a null check.

Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
---
 drivers/scsi/aic7xxx/aic7xxx_core.c | 72 +++++++++++++++--------------
 1 file changed, 37 insertions(+), 35 deletions(-)
diff mbox series

Patch

diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index 4b04ab8908f8..3a1cd6a0334e 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -1382,43 +1382,45 @@  ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
 		u_int i;
 
 		scb = ahc_lookup_scb(ahc, scbindex);
-		for (i = 0; i < num_phases; i++) {
-			if (lastphase == ahc_phase_table[i].phase)
-				break;
-		}
-		ahc_print_path(ahc, scb);
-		printk("data overrun detected %s."
-		       "  Tag == 0x%x.\n",
-		       ahc_phase_table[i].phasemsg,
-		       scb->hscb->tag);
-		ahc_print_path(ahc, scb);
-		printk("%s seen Data Phase.  Length = %ld.  NumSGs = %d.\n",
-		       ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
-		       ahc_get_transfer_length(scb), scb->sg_count);
-		if (scb->sg_count > 0) {
-			for (i = 0; i < scb->sg_count; i++) {
-
-				printk("sg[%d] - Addr 0x%x%x : Length %d\n",
-				       i,
-				       (ahc_le32toh(scb->sg_list[i].len) >> 24
-					& SG_HIGH_ADDR_BITS),
-				       ahc_le32toh(scb->sg_list[i].addr),
-				       ahc_le32toh(scb->sg_list[i].len)
-				       & AHC_SG_LEN_MASK);
+		if (scb != NULL) {
+			for (i = 0; i < num_phases; i++) {
+				if (lastphase == ahc_phase_table[i].phase)
+					break;
 			}
+			ahc_print_path(ahc, scb);
+			printk("data overrun detected %s."
+				"  Tag == 0x%x.\n",
+				ahc_phase_table[i].phasemsg,
+				scb->hscb->tag);
+			ahc_print_path(ahc, scb);
+			printk("%s seen Data Phase.  Length = %ld.  NumSGs = %d.\n",
+				ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
+				ahc_get_transfer_length(scb), scb->sg_count);
+			if (scb->sg_count > 0) {
+				for (i = 0; i < scb->sg_count; i++) {
+
+					printk("sg[%d] - Addr 0x%x%x : Length %d\n",
+						i,
+						(ahc_le32toh(scb->sg_list[i].len) >> 24
+						& SG_HIGH_ADDR_BITS),
+						ahc_le32toh(scb->sg_list[i].addr),
+						ahc_le32toh(scb->sg_list[i].len)
+						& AHC_SG_LEN_MASK);
+				}
+			}
+			/*
+			* Set this and it will take effect when the
+			* target does a command complete.
+			*/
+			ahc_freeze_devq(ahc, scb);
+			if ((scb->flags & SCB_SENSE) == 0) {
+				ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
+			} else {
+				scb->flags &= ~SCB_SENSE;
+				ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
+			}
+			ahc_freeze_scb(scb);
 		}
-		/*
-		 * Set this and it will take effect when the
-		 * target does a command complete.
-		 */
-		ahc_freeze_devq(ahc, scb);
-		if ((scb->flags & SCB_SENSE) == 0) {
-			ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
-		} else {
-			scb->flags &= ~SCB_SENSE;
-			ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
-		}
-		ahc_freeze_scb(scb);
 
 		if ((ahc->features & AHC_ULTRA2) != 0) {
 			/*