diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-19 23:09:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-19 23:09:55 -0400 |
commit | 820bf5c419e4b85298e5c3001bd1b5be46d60765 (patch) | |
tree | 2f7321d28c194871b38f7e90fa68a46ae2df5ab1 | |
parent | b8350cd00407a121e10727d9591026d6194714b7 (diff) | |
parent | 3e0097499839e0fe3af380410eababe5a47c4cf9 (diff) |
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley:
"This is a set of five small fixes: one is a null deref fix which is
pretty critical for the fc transport class and one fixes a potential
security issue of sg leaking kernel information"
* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: sg: fixup infoleak when using SG_GET_REQUEST_TABLE
scsi: sg: factor out sg_fill_request_table()
scsi: sd: Remove unnecessary condition in sd_read_block_limits()
scsi: acornscsi: fix build error
scsi: scsi_transport_fc: fix NULL pointer dereference in fc_bsg_job_timeout
-rw-r--r-- | drivers/scsi/arm/acornscsi.c | 6 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_fc.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sg.c | 64 |
4 files changed, 40 insertions, 34 deletions
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 690816f3c6af..421fe869a11e 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c | |||
@@ -2725,9 +2725,9 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt) | |||
2725 | * Params : SCpnt - command causing reset | 2725 | * Params : SCpnt - command causing reset |
2726 | * Returns : one of SCSI_RESET_ macros | 2726 | * Returns : one of SCSI_RESET_ macros |
2727 | */ | 2727 | */ |
2728 | int acornscsi_host_reset(struct Scsi_Host *shpnt) | 2728 | int acornscsi_host_reset(struct scsi_cmnd *SCpnt) |
2729 | { | 2729 | { |
2730 | AS_Host *host = (AS_Host *)shpnt->hostdata; | 2730 | AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; |
2731 | struct scsi_cmnd *SCptr; | 2731 | struct scsi_cmnd *SCptr; |
2732 | 2732 | ||
2733 | host->stats.resets += 1; | 2733 | host->stats.resets += 1; |
@@ -2741,7 +2741,7 @@ int acornscsi_host_reset(struct Scsi_Host *shpnt) | |||
2741 | 2741 | ||
2742 | printk(KERN_WARNING "acornscsi_reset: "); | 2742 | printk(KERN_WARNING "acornscsi_reset: "); |
2743 | print_sbic_status(asr, ssr, host->scsi.phase); | 2743 | print_sbic_status(asr, ssr, host->scsi.phase); |
2744 | for (devidx = 0; devidx < 9; devidx ++) { | 2744 | for (devidx = 0; devidx < 9; devidx++) |
2745 | acornscsi_dumplog(host, devidx); | 2745 | acornscsi_dumplog(host, devidx); |
2746 | } | 2746 | } |
2747 | #endif | 2747 | #endif |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 3c6bc0081fcb..ba9d70f8a6a1 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -3571,7 +3571,7 @@ fc_vport_sched_delete(struct work_struct *work) | |||
3571 | static enum blk_eh_timer_return | 3571 | static enum blk_eh_timer_return |
3572 | fc_bsg_job_timeout(struct request *req) | 3572 | fc_bsg_job_timeout(struct request *req) |
3573 | { | 3573 | { |
3574 | struct bsg_job *job = (void *) req->special; | 3574 | struct bsg_job *job = blk_mq_rq_to_pdu(req); |
3575 | struct Scsi_Host *shost = fc_bsg_to_shost(job); | 3575 | struct Scsi_Host *shost = fc_bsg_to_shost(job); |
3576 | struct fc_rport *rport = fc_bsg_to_rport(job); | 3576 | struct fc_rport *rport = fc_bsg_to_rport(job); |
3577 | struct fc_internal *i = to_fc_internal(shost->transportt); | 3577 | struct fc_internal *i = to_fc_internal(shost->transportt); |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 11c1738c2100..fb9f8b5f4673 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -2915,8 +2915,6 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
2915 | sd_config_discard(sdkp, SD_LBP_WS16); | 2915 | sd_config_discard(sdkp, SD_LBP_WS16); |
2916 | else if (sdkp->lbpws10) | 2916 | else if (sdkp->lbpws10) |
2917 | sd_config_discard(sdkp, SD_LBP_WS10); | 2917 | sd_config_discard(sdkp, SD_LBP_WS10); |
2918 | else if (sdkp->lbpu && sdkp->max_unmap_blocks) | ||
2919 | sd_config_discard(sdkp, SD_LBP_UNMAP); | ||
2920 | else | 2918 | else |
2921 | sd_config_discard(sdkp, SD_LBP_DISABLE); | 2919 | sd_config_discard(sdkp, SD_LBP_DISABLE); |
2922 | } | 2920 | } |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index cf0e71db9e51..0419c2298eab 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -828,6 +828,39 @@ static int max_sectors_bytes(struct request_queue *q) | |||
828 | return max_sectors << 9; | 828 | return max_sectors << 9; |
829 | } | 829 | } |
830 | 830 | ||
831 | static void | ||
832 | sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo) | ||
833 | { | ||
834 | Sg_request *srp; | ||
835 | int val; | ||
836 | unsigned int ms; | ||
837 | |||
838 | val = 0; | ||
839 | list_for_each_entry(srp, &sfp->rq_list, entry) { | ||
840 | if (val > SG_MAX_QUEUE) | ||
841 | break; | ||
842 | rinfo[val].req_state = srp->done + 1; | ||
843 | rinfo[val].problem = | ||
844 | srp->header.masked_status & | ||
845 | srp->header.host_status & | ||
846 | srp->header.driver_status; | ||
847 | if (srp->done) | ||
848 | rinfo[val].duration = | ||
849 | srp->header.duration; | ||
850 | else { | ||
851 | ms = jiffies_to_msecs(jiffies); | ||
852 | rinfo[val].duration = | ||
853 | (ms > srp->header.duration) ? | ||
854 | (ms - srp->header.duration) : 0; | ||
855 | } | ||
856 | rinfo[val].orphan = srp->orphan; | ||
857 | rinfo[val].sg_io_owned = srp->sg_io_owned; | ||
858 | rinfo[val].pack_id = srp->header.pack_id; | ||
859 | rinfo[val].usr_ptr = srp->header.usr_ptr; | ||
860 | val++; | ||
861 | } | ||
862 | } | ||
863 | |||
831 | static long | 864 | static long |
832 | sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) | 865 | sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) |
833 | { | 866 | { |
@@ -1012,38 +1045,13 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) | |||
1012 | return -EFAULT; | 1045 | return -EFAULT; |
1013 | else { | 1046 | else { |
1014 | sg_req_info_t *rinfo; | 1047 | sg_req_info_t *rinfo; |
1015 | unsigned int ms; | ||
1016 | 1048 | ||
1017 | rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, | 1049 | rinfo = kzalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, |
1018 | GFP_KERNEL); | 1050 | GFP_KERNEL); |
1019 | if (!rinfo) | 1051 | if (!rinfo) |
1020 | return -ENOMEM; | 1052 | return -ENOMEM; |
1021 | read_lock_irqsave(&sfp->rq_list_lock, iflags); | 1053 | read_lock_irqsave(&sfp->rq_list_lock, iflags); |
1022 | val = 0; | 1054 | sg_fill_request_table(sfp, rinfo); |
1023 | list_for_each_entry(srp, &sfp->rq_list, entry) { | ||
1024 | if (val >= SG_MAX_QUEUE) | ||
1025 | break; | ||
1026 | memset(&rinfo[val], 0, SZ_SG_REQ_INFO); | ||
1027 | rinfo[val].req_state = srp->done + 1; | ||
1028 | rinfo[val].problem = | ||
1029 | srp->header.masked_status & | ||
1030 | srp->header.host_status & | ||
1031 | srp->header.driver_status; | ||
1032 | if (srp->done) | ||
1033 | rinfo[val].duration = | ||
1034 | srp->header.duration; | ||
1035 | else { | ||
1036 | ms = jiffies_to_msecs(jiffies); | ||
1037 | rinfo[val].duration = | ||
1038 | (ms > srp->header.duration) ? | ||
1039 | (ms - srp->header.duration) : 0; | ||
1040 | } | ||
1041 | rinfo[val].orphan = srp->orphan; | ||
1042 | rinfo[val].sg_io_owned = srp->sg_io_owned; | ||
1043 | rinfo[val].pack_id = srp->header.pack_id; | ||
1044 | rinfo[val].usr_ptr = srp->header.usr_ptr; | ||
1045 | val++; | ||
1046 | } | ||
1047 | read_unlock_irqrestore(&sfp->rq_list_lock, iflags); | 1055 | read_unlock_irqrestore(&sfp->rq_list_lock, iflags); |
1048 | result = __copy_to_user(p, rinfo, | 1056 | result = __copy_to_user(p, rinfo, |
1049 | SZ_SG_REQ_INFO * SG_MAX_QUEUE); | 1057 | SZ_SG_REQ_INFO * SG_MAX_QUEUE); |