[patch] check length passed to SG_NEXT_CMD_LEN

2017-03-03 Thread Peter Chang
now that i think i've got gmail not marking everything as spam...

\p
From 93409c62db49d15105390315a685e54083029bee Mon Sep 17 00:00:00 2001
From: peter chang <d...@google.com>
Date: Wed, 15 Feb 2017 14:11:54 -0800
Subject: [PATCH] [sg] check length passed to SG_NEXT_CMD_LEN

the user can control the size of the next command passed along, but
the value passed to the ioctl isn't checked against the usable
max command size.

Change-Id: I9ac2ae07c35cf5fda62d7afad32c8d9ab6a9ea1d
Tested: sanity checked w/ calling the ioctl w/ a bogus size
---
 drivers/scsi/sg.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 9c5c5f2b3962..b47a369cb71c 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -976,6 +976,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
 		result = get_user(val, ip);
 		if (result)
 			return result;
+		if (val > SG_MAX_CDB_SIZE)
+			return -ENOMEM;
 		sfp->next_cmd_len = (val > 0) ? val : 0;
 		return 0;
 	case SG_GET_VERSION_NUM:
-- 
2.12.0.rc1.440.g5b76565f74-goog



[PATCH] set a base index for libsas based ata devices

2016-12-20 Thread Peter Chang
we discovered this when futzing w/ the queue depth parameter for ata
disks behind the pm8006 controller. setting depth == 1 should disable
ncq, but the sysfs part silently fails and we continue sending the
fpdma command variants. no one else probably cares about the disabling
ncq path, but we do like to test.

anyway, adding both the ide and scsi lists because i'm not quite sure
there's a separate libsas list and a single commit seems better for
this.

\p
From 6bdfcb35a074d9c58c180f8c512706faf7d6c7cb Mon Sep 17 00:00:00 2001
From: peter chang <d...@google.com>
Date: Tue, 20 Dec 2016 09:48:45 -0800
Subject: [PATCH] set a base index for libsas based ata devices

libsas hosts allow multiple links, but when the controller
supports SATA devices control is handed to libata. this means
that an attached scsi device will be setup properly, but device
management requests and sysfs futzing don't get routed correctly
because the device lookup fails.

Tested:
- pre-patch:
jkgg70:~# ls -d /sys/block/sd*
/sys/block/sda
jkgg70:~# modprobe pm80xx
jkgg70:~# cat /sys/block/sdb/device/queue_depth
31
jkgg70:~# echo 1 > /sys/block/sdb/device/queue_depth
jkgg70:~# cat /sys/block/sdb/device/queue_depth
31
- post-patch:
jkgg70:~# modprobe pm80xx
jkgg70:~# cat /sys/block/sdb/device/queue_depth
31
jkgg70:~# echo 1 > /sys/block/sdb/device/queue_depth
jkgg70:~# cat /sys/block/sdb/device/queue_depth
1

Signed-off-by: peter chang <d...@google.com>
---
 drivers/ata/libata-scsi.c   | 33 -
 drivers/scsi/libsas/sas_scsi_host.c |  4 
 include/linux/libata.h  |  3 +++
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 1f863e7..340f144 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1088,7 +1088,7 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
  *	passthrough command, so we use the following sense data:
  *	sk = RECOVERED ERROR
  *	asc,ascq = ATA PASS-THROUGH INFORMATION AVAILABLE
- *  
+ *
  *
  *	LOCKING:
  *	None.
@@ -3052,6 +3052,16 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
 
 static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
 {
+	/* adjust if this port is behind a libsas host rather than a
+	 * direct libata host. warn and fail if somehow we got out of
+	 * sync and we've a negative device number.
+	 */
+	devno -= ap->link.sas_host_base;
+	if (unlikely(devno < 0)) {
+		WARN_ON(devno < 0);
+		return NULL;
+	}
+
 	if (!sata_pmp_attached(ap)) {
 		if (likely(devno < ata_link_max_devices(>link)))
 			return >link.device[devno];
@@ -4332,6 +4342,27 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
 }
 
 /**
+ *	ata_sas_set_link_base - set the libata link's 'base' because
+ *	libsas hosts have more ports / links.
+ *	@ap: ATA port to which the target is attached
+ *	@starget: SCSI target being attached
+ */
+void ata_sas_set_link_base(struct ata_port *ap, struct scsi_target *starget)
+{
+	unsigned int host_base;
+
+	if (!sata_pmp_attached(ap)) {
+		WARN_ON(starget->channel);
+		host_base = starget->id;
+	} else {
+		WARN_ON(starget->id);
+		host_base = starget->channel;
+	}
+	ap->link.sas_host_base = host_base;
+}
+EXPORT_SYMBOL_GPL(ata_sas_set_link_base);
+
+/**
  *	ata_scsi_simulate - simulate SCSI command on ATA device
  *	@dev: the target device
  *	@cmd: SCSI command being sent to device.
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 519dac4..d8300bc 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -859,6 +859,10 @@ int sas_target_alloc(struct scsi_target *starget)
 
 	kref_get(_dev->kref);
 	starget->hostdata = found_dev;
+
+	if (dev_is_sata(found_dev))
+		ata_sas_set_link_base(found_dev->sata_dev.ap, starget);
+
 	return 0;
 }
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index c170be5..323811f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -791,6 +791,7 @@ struct ata_acpi_gtm {
 struct ata_link {
 	struct ata_port		*ap;
 	int			pmp;		/* port multiplier port # */
+	int			sas_host_base;	/* host relative id */
 
 	struct device		tdev;
 	unsigned int		active_tag;	/* active tag on this link */
@@ -1130,6 +1131,8 @@ extern int ata_sas_port_start(struct ata_port *ap);
 extern void ata_sas_port_stop(struct ata_port *ap);
 extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *);
 extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap);
+extern void ata_sas_set_link_base(struct ata_port *ap,
+  struct scsi_target *starget);
 extern int sata_scr_valid(struct ata_link *link);
 extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
 extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
-- 
2.8.0.rc3.226.g39d4020



Re: Help with mpt2sas kernel message

2013-12-12 Thread Peter Chang
2013/12/12 Wakko Warner wa...@animx.eu.org:
 Kernel: vanilla 3.7.2.

 I have 2 mpt2sas controllers.  I'm running a md check on the 2 arrays that I
 have (one per card).  I'm seeing this in my kernel log (last 4 lines):
 2013-12-10 19:52:10 kame kernel:[1558186.193904] mpt2sas0: 
 log_info(0x3108): originator(PL), code(0x08), sub_code(0x)

'all ncq IOs fail when one ncq io encounters an error'

 I'd also like to know which card mpt2sas0 is.  Is it the one that has the
 lower numbered pci bus?

it's the first controller enumerated on pci, so probably the lowest number.

\p
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [SCSI] sg: Fix user memory corruption when SG_IO is interrupted by a signal

2013-08-05 Thread Peter Chang
2013/8/5 Roland Dreier rol...@kernel.org:
 From: Roland Dreier rol...@purestorage.com

 There is a nasty bug in the SCSI SG_IO ioctl that in some circumstances
 leads to one process writing data into the address space of some other
 random unrelated process if the ioctl is interrupted by a signal.
 What happens is the following:

  - A process issues an SG_IO ioctl with direction DXFER_FROM_DEV (ie the
underlying SCSI command will transfer data from the SCSI device to
the buffer provided in the ioctl)

  - Before the command finishes, a signal is sent to the process waiting
in the ioctl.  This will end up waking up the sg_ioctl() code:

 result = wait_event_interruptible(sfp-read_wait,
 (srp_done(sfp, srp) || sdp-detached));

but neither srp_done() nor sdp-detached is true, so we end up just
setting srp-orphan and returning to userspace:

 srp-orphan = 1;
 write_unlock_irq(sfp-rq_list_lock);
 return result;  /* -ERESTARTSYS because signal hit process */

At this point the original process is done with the ioctl and
blithely goes ahead handling the signal, reissuing the ioctl, etc.

i think that an additional issue here is that part of reissuing the
ioctl is re-queueing the command. since the re-queue is at the front
of the block queue there are issues if the command is non-idempotent.

we have a local fix that gets rid of most of the orphan stuff and
re-waiting if a non-fatal signal was waiting. simpler than unmapping
but maybe we're missing some other interesting case?

\p
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html