Skip to content

Commit c9ddf73

Browse files
KAGA-KOKOmartinkpetersen
authored andcommitted
scsi: scsi_transport_srp: Fix shost to rport translation
Since an SRP remote port is attached as a child to shost->shost_gendev and as the only child, the translation from the shost pointer into an rport pointer must happen by looking up the shost child that is an rport. This patch fixes the following KASAN complaint: BUG: KASAN: slab-out-of-bounds in srp_timed_out+0x57/0x110 [scsi_transport_srp] Read of size 4 at addr ffff880035d3fcc0 by task kworker/1:0H/19 CPU: 1 PID: 19 Comm: kworker/1:0H Not tainted 4.16.0-rc3-dbg+ #1 Workqueue: kblockd blk_mq_timeout_work Call Trace: dump_stack+0x85/0xc7 print_address_description+0x65/0x270 kasan_report+0x231/0x350 srp_timed_out+0x57/0x110 [scsi_transport_srp] scsi_times_out+0xc7/0x3f0 [scsi_mod] blk_mq_terminate_expired+0xc2/0x140 bt_iter+0xbc/0xd0 blk_mq_queue_tag_busy_iter+0x1c7/0x350 blk_mq_timeout_work+0x325/0x3f0 process_one_work+0x441/0xa50 worker_thread+0x76/0x6c0 kthread+0x1b2/0x1d0 ret_from_fork+0x24/0x30 Fixes: e68ca75 ("scsi_transport_srp: Reduce failover time") Signed-off-by: Bart Van Assche <[email protected]> Cc: Hannes Reinecke <[email protected]> Cc: Johannes Thumshirn <[email protected]> Cc: Jason Gunthorpe <[email protected]> Cc: Doug Ledford <[email protected]> Cc: Laurence Oberman <[email protected]> Cc: [email protected] Reviewed-by: Johannes Thumshirn <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent a45b599 commit c9ddf73

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

drivers/scsi/scsi_transport_srp.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ struct srp_internal {
5151
struct transport_container rport_attr_cont;
5252
};
5353

54+
static int scsi_is_srp_rport(const struct device *dev);
55+
5456
#define to_srp_internal(tmpl) container_of(tmpl, struct srp_internal, t)
5557

5658
#define dev_to_rport(d) container_of(d, struct srp_rport, dev)
@@ -60,9 +62,24 @@ static inline struct Scsi_Host *rport_to_shost(struct srp_rport *r)
6062
return dev_to_shost(r->dev.parent);
6163
}
6264

65+
static int find_child_rport(struct device *dev, void *data)
66+
{
67+
struct device **child = data;
68+
69+
if (scsi_is_srp_rport(dev)) {
70+
WARN_ON_ONCE(*child);
71+
*child = dev;
72+
}
73+
return 0;
74+
}
75+
6376
static inline struct srp_rport *shost_to_rport(struct Scsi_Host *shost)
6477
{
65-
return transport_class_to_srp_rport(&shost->shost_gendev);
78+
struct device *child = NULL;
79+
80+
WARN_ON_ONCE(device_for_each_child(&shost->shost_gendev, &child,
81+
find_child_rport) < 0);
82+
return child ? dev_to_rport(child) : NULL;
6683
}
6784

6885
/**
@@ -600,7 +617,8 @@ enum blk_eh_timer_return srp_timed_out(struct scsi_cmnd *scmd)
600617
struct srp_rport *rport = shost_to_rport(shost);
601618

602619
pr_debug("timeout for sdev %s\n", dev_name(&sdev->sdev_gendev));
603-
return rport->fast_io_fail_tmo < 0 && rport->dev_loss_tmo < 0 &&
620+
return rport && rport->fast_io_fail_tmo < 0 &&
621+
rport->dev_loss_tmo < 0 &&
604622
i->f->reset_timer_if_blocked && scsi_device_blocked(sdev) ?
605623
BLK_EH_RESET_TIMER : BLK_EH_NOT_HANDLED;
606624
}

0 commit comments

Comments
 (0)