Skip to content

Commit 846e8dd

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
James writes: "SCSI fixes on 20180925 Nine obvious bug fixes mostly in individual drivers. The target fix is of particular importance because it's CVE related." * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: sd: don't crash the host on invalid commands scsi: ipr: System hung while dlpar adding primary ipr adapter back scsi: target: iscsi: Use bin2hex instead of a re-implementation scsi: target: iscsi: Use hex2bin instead of a re-implementation scsi: lpfc: Synchronize access to remoteport via rport scsi: ufs: Disable blk-mq for now scsi: sd: Contribute to randomness when running rotational device scsi: ibmvscsis: Ensure partition name is properly NUL terminated scsi: ibmvscsis: Fix a stringop-overflow warning
2 parents bfb0e9b + f1f1fad commit 846e8dd

File tree

9 files changed

+116
-90
lines changed

9 files changed

+116
-90
lines changed

drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3474,11 +3474,10 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
34743474
vscsi->dds.window[LOCAL].liobn,
34753475
vscsi->dds.window[REMOTE].liobn);
34763476

3477-
strcpy(vscsi->eye, "VSCSI ");
3478-
strncat(vscsi->eye, vdev->name, MAX_EYE);
3477+
snprintf(vscsi->eye, sizeof(vscsi->eye), "VSCSI %s", vdev->name);
34793478

34803479
vscsi->dds.unit_id = vdev->unit_address;
3481-
strncpy(vscsi->dds.partition_name, partition_name,
3480+
strscpy(vscsi->dds.partition_name, partition_name,
34823481
sizeof(vscsi->dds.partition_name));
34833482
vscsi->dds.partition_num = partition_number;
34843483

drivers/scsi/ipr.c

Lines changed: 61 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3335,6 +3335,65 @@ static void ipr_release_dump(struct kref *kref)
33353335
LEAVE;
33363336
}
33373337

3338+
static void ipr_add_remove_thread(struct work_struct *work)
3339+
{
3340+
unsigned long lock_flags;
3341+
struct ipr_resource_entry *res;
3342+
struct scsi_device *sdev;
3343+
struct ipr_ioa_cfg *ioa_cfg =
3344+
container_of(work, struct ipr_ioa_cfg, scsi_add_work_q);
3345+
u8 bus, target, lun;
3346+
int did_work;
3347+
3348+
ENTER;
3349+
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
3350+
3351+
restart:
3352+
do {
3353+
did_work = 0;
3354+
if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) {
3355+
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3356+
return;
3357+
}
3358+
3359+
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
3360+
if (res->del_from_ml && res->sdev) {
3361+
did_work = 1;
3362+
sdev = res->sdev;
3363+
if (!scsi_device_get(sdev)) {
3364+
if (!res->add_to_ml)
3365+
list_move_tail(&res->queue, &ioa_cfg->free_res_q);
3366+
else
3367+
res->del_from_ml = 0;
3368+
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3369+
scsi_remove_device(sdev);
3370+
scsi_device_put(sdev);
3371+
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
3372+
}
3373+
break;
3374+
}
3375+
}
3376+
} while (did_work);
3377+
3378+
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
3379+
if (res->add_to_ml) {
3380+
bus = res->bus;
3381+
target = res->target;
3382+
lun = res->lun;
3383+
res->add_to_ml = 0;
3384+
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3385+
scsi_add_device(ioa_cfg->host, bus, target, lun);
3386+
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
3387+
goto restart;
3388+
}
3389+
}
3390+
3391+
ioa_cfg->scan_done = 1;
3392+
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3393+
kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
3394+
LEAVE;
3395+
}
3396+
33383397
/**
33393398
* ipr_worker_thread - Worker thread
33403399
* @work: ioa config struct
@@ -3349,13 +3408,9 @@ static void ipr_release_dump(struct kref *kref)
33493408
static void ipr_worker_thread(struct work_struct *work)
33503409
{
33513410
unsigned long lock_flags;
3352-
struct ipr_resource_entry *res;
3353-
struct scsi_device *sdev;
33543411
struct ipr_dump *dump;
33553412
struct ipr_ioa_cfg *ioa_cfg =
33563413
container_of(work, struct ipr_ioa_cfg, work_q);
3357-
u8 bus, target, lun;
3358-
int did_work;
33593414

33603415
ENTER;
33613416
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -3393,49 +3448,9 @@ static void ipr_worker_thread(struct work_struct *work)
33933448
return;
33943449
}
33953450

3396-
restart:
3397-
do {
3398-
did_work = 0;
3399-
if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) {
3400-
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3401-
return;
3402-
}
3451+
schedule_work(&ioa_cfg->scsi_add_work_q);
34033452

3404-
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
3405-
if (res->del_from_ml && res->sdev) {
3406-
did_work = 1;
3407-
sdev = res->sdev;
3408-
if (!scsi_device_get(sdev)) {
3409-
if (!res->add_to_ml)
3410-
list_move_tail(&res->queue, &ioa_cfg->free_res_q);
3411-
else
3412-
res->del_from_ml = 0;
3413-
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3414-
scsi_remove_device(sdev);
3415-
scsi_device_put(sdev);
3416-
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
3417-
}
3418-
break;
3419-
}
3420-
}
3421-
} while (did_work);
3422-
3423-
list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
3424-
if (res->add_to_ml) {
3425-
bus = res->bus;
3426-
target = res->target;
3427-
lun = res->lun;
3428-
res->add_to_ml = 0;
3429-
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3430-
scsi_add_device(ioa_cfg->host, bus, target, lun);
3431-
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
3432-
goto restart;
3433-
}
3434-
}
3435-
3436-
ioa_cfg->scan_done = 1;
34373453
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3438-
kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
34393454
LEAVE;
34403455
}
34413456

@@ -9933,6 +9948,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
99339948
INIT_LIST_HEAD(&ioa_cfg->free_res_q);
99349949
INIT_LIST_HEAD(&ioa_cfg->used_res_q);
99359950
INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread);
9951+
INIT_WORK(&ioa_cfg->scsi_add_work_q, ipr_add_remove_thread);
99369952
init_waitqueue_head(&ioa_cfg->reset_wait_q);
99379953
init_waitqueue_head(&ioa_cfg->msi_wait_q);
99389954
init_waitqueue_head(&ioa_cfg->eeh_wait_q);

drivers/scsi/ipr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,7 @@ struct ipr_ioa_cfg {
15751575
u8 saved_mode_page_len;
15761576

15771577
struct work_struct work_q;
1578+
struct work_struct scsi_add_work_q;
15781579
struct workqueue_struct *reset_work_q;
15791580

15801581
wait_queue_head_t reset_wait_q;

drivers/scsi/lpfc/lpfc_attr.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -360,12 +360,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
360360
goto buffer_done;
361361

362362
list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
363+
nrport = NULL;
364+
spin_lock(&vport->phba->hbalock);
363365
rport = lpfc_ndlp_get_nrport(ndlp);
364-
if (!rport)
365-
continue;
366-
367-
/* local short-hand pointer. */
368-
nrport = rport->remoteport;
366+
if (rport)
367+
nrport = rport->remoteport;
368+
spin_unlock(&vport->phba->hbalock);
369369
if (!nrport)
370370
continue;
371371

@@ -3386,6 +3386,7 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
33863386
struct lpfc_nodelist *ndlp;
33873387
#if (IS_ENABLED(CONFIG_NVME_FC))
33883388
struct lpfc_nvme_rport *rport;
3389+
struct nvme_fc_remote_port *remoteport = NULL;
33893390
#endif
33903391

33913392
shost = lpfc_shost_from_vport(vport);
@@ -3396,8 +3397,12 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
33963397
if (ndlp->rport)
33973398
ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
33983399
#if (IS_ENABLED(CONFIG_NVME_FC))
3400+
spin_lock(&vport->phba->hbalock);
33993401
rport = lpfc_ndlp_get_nrport(ndlp);
34003402
if (rport)
3403+
remoteport = rport->remoteport;
3404+
spin_unlock(&vport->phba->hbalock);
3405+
if (remoteport)
34013406
nvme_fc_set_remoteport_devloss(rport->remoteport,
34023407
vport->cfg_devloss_tmo);
34033408
#endif

drivers/scsi/lpfc/lpfc_debugfs.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
551551
unsigned char *statep;
552552
struct nvme_fc_local_port *localport;
553553
struct lpfc_nvmet_tgtport *tgtp;
554-
struct nvme_fc_remote_port *nrport;
554+
struct nvme_fc_remote_port *nrport = NULL;
555555
struct lpfc_nvme_rport *rport;
556556

557557
cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
@@ -696,11 +696,11 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
696696
len += snprintf(buf + len, size - len, "\tRport List:\n");
697697
list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
698698
/* local short-hand pointer. */
699+
spin_lock(&phba->hbalock);
699700
rport = lpfc_ndlp_get_nrport(ndlp);
700-
if (!rport)
701-
continue;
702-
703-
nrport = rport->remoteport;
701+
if (rport)
702+
nrport = rport->remoteport;
703+
spin_unlock(&phba->hbalock);
704704
if (!nrport)
705705
continue;
706706

drivers/scsi/lpfc/lpfc_nvme.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,7 +2725,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
27252725
rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
27262726
rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
27272727

2728+
spin_lock_irq(&vport->phba->hbalock);
27282729
oldrport = lpfc_ndlp_get_nrport(ndlp);
2730+
spin_unlock_irq(&vport->phba->hbalock);
27292731
if (!oldrport)
27302732
lpfc_nlp_get(ndlp);
27312733

@@ -2840,7 +2842,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
28402842
struct nvme_fc_local_port *localport;
28412843
struct lpfc_nvme_lport *lport;
28422844
struct lpfc_nvme_rport *rport;
2843-
struct nvme_fc_remote_port *remoteport;
2845+
struct nvme_fc_remote_port *remoteport = NULL;
28442846

28452847
localport = vport->localport;
28462848

@@ -2854,11 +2856,14 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
28542856
if (!lport)
28552857
goto input_err;
28562858

2859+
spin_lock_irq(&vport->phba->hbalock);
28572860
rport = lpfc_ndlp_get_nrport(ndlp);
2858-
if (!rport)
2861+
if (rport)
2862+
remoteport = rport->remoteport;
2863+
spin_unlock_irq(&vport->phba->hbalock);
2864+
if (!remoteport)
28592865
goto input_err;
28602866

2861-
remoteport = rport->remoteport;
28622867
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
28632868
"6033 Unreg nvme remoteport %p, portname x%llx, "
28642869
"port_id x%06x, portstate x%x port type x%x\n",

drivers/scsi/sd.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1276,7 +1276,8 @@ static int sd_init_command(struct scsi_cmnd *cmd)
12761276
case REQ_OP_ZONE_RESET:
12771277
return sd_zbc_setup_reset_cmnd(cmd);
12781278
default:
1279-
BUG();
1279+
WARN_ON_ONCE(1);
1280+
return BLKPREP_KILL;
12801281
}
12811282
}
12821283

@@ -2959,6 +2960,9 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
29592960
if (rot == 1) {
29602961
blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
29612962
blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q);
2963+
} else {
2964+
blk_queue_flag_clear(QUEUE_FLAG_NONROT, q);
2965+
blk_queue_flag_set(QUEUE_FLAG_ADD_RANDOM, q);
29622966
}
29632967

29642968
if (sdkp->device->type == TYPE_ZBC) {

drivers/scsi/ufs/ufshcd.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7940,6 +7940,13 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
79407940
err = -ENOMEM;
79417941
goto out_error;
79427942
}
7943+
7944+
/*
7945+
* Do not use blk-mq at this time because blk-mq does not support
7946+
* runtime pm.
7947+
*/
7948+
host->use_blk_mq = false;
7949+
79437950
hba = shost_priv(host);
79447951
hba->host = host;
79457952
hba->dev = dev;

drivers/target/iscsi/iscsi_target_auth.c

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,6 @@
2626
#include "iscsi_target_nego.h"
2727
#include "iscsi_target_auth.h"
2828

29-
static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len)
30-
{
31-
int j = DIV_ROUND_UP(len, 2), rc;
32-
33-
rc = hex2bin(dst, src, j);
34-
if (rc < 0)
35-
pr_debug("CHAP string contains non hex digit symbols\n");
36-
37-
dst[j] = '\0';
38-
return j;
39-
}
40-
41-
static void chap_binaryhex_to_asciihex(char *dst, char *src, int src_len)
42-
{
43-
int i;
44-
45-
for (i = 0; i < src_len; i++) {
46-
sprintf(&dst[i*2], "%02x", (int) src[i] & 0xff);
47-
}
48-
}
49-
5029
static int chap_gen_challenge(
5130
struct iscsi_conn *conn,
5231
int caller,
@@ -62,7 +41,7 @@ static int chap_gen_challenge(
6241
ret = get_random_bytes_wait(chap->challenge, CHAP_CHALLENGE_LENGTH);
6342
if (unlikely(ret))
6443
return ret;
65-
chap_binaryhex_to_asciihex(challenge_asciihex, chap->challenge,
44+
bin2hex(challenge_asciihex, chap->challenge,
6645
CHAP_CHALLENGE_LENGTH);
6746
/*
6847
* Set CHAP_C, and copy the generated challenge into c_str.
@@ -248,9 +227,16 @@ static int chap_server_compute_md5(
248227
pr_err("Could not find CHAP_R.\n");
249228
goto out;
250229
}
230+
if (strlen(chap_r) != MD5_SIGNATURE_SIZE * 2) {
231+
pr_err("Malformed CHAP_R\n");
232+
goto out;
233+
}
234+
if (hex2bin(client_digest, chap_r, MD5_SIGNATURE_SIZE) < 0) {
235+
pr_err("Malformed CHAP_R\n");
236+
goto out;
237+
}
251238

252239
pr_debug("[server] Got CHAP_R=%s\n", chap_r);
253-
chap_string_to_hex(client_digest, chap_r, strlen(chap_r));
254240

255241
tfm = crypto_alloc_shash("md5", 0, 0);
256242
if (IS_ERR(tfm)) {
@@ -294,7 +280,7 @@ static int chap_server_compute_md5(
294280
goto out;
295281
}
296282

297-
chap_binaryhex_to_asciihex(response, server_digest, MD5_SIGNATURE_SIZE);
283+
bin2hex(response, server_digest, MD5_SIGNATURE_SIZE);
298284
pr_debug("[server] MD5 Server Digest: %s\n", response);
299285

300286
if (memcmp(server_digest, client_digest, MD5_SIGNATURE_SIZE) != 0) {
@@ -349,9 +335,7 @@ static int chap_server_compute_md5(
349335
pr_err("Could not find CHAP_C.\n");
350336
goto out;
351337
}
352-
pr_debug("[server] Got CHAP_C=%s\n", challenge);
353-
challenge_len = chap_string_to_hex(challenge_binhex, challenge,
354-
strlen(challenge));
338+
challenge_len = DIV_ROUND_UP(strlen(challenge), 2);
355339
if (!challenge_len) {
356340
pr_err("Unable to convert incoming challenge\n");
357341
goto out;
@@ -360,6 +344,11 @@ static int chap_server_compute_md5(
360344
pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
361345
goto out;
362346
}
347+
if (hex2bin(challenge_binhex, challenge, challenge_len) < 0) {
348+
pr_err("Malformed CHAP_C\n");
349+
goto out;
350+
}
351+
pr_debug("[server] Got CHAP_C=%s\n", challenge);
363352
/*
364353
* During mutual authentication, the CHAP_C generated by the
365354
* initiator must not match the original CHAP_C generated by
@@ -413,7 +402,7 @@ static int chap_server_compute_md5(
413402
/*
414403
* Convert response from binary hex to ascii hext.
415404
*/
416-
chap_binaryhex_to_asciihex(response, digest, MD5_SIGNATURE_SIZE);
405+
bin2hex(response, digest, MD5_SIGNATURE_SIZE);
417406
*nr_out_len += sprintf(nr_out_ptr + *nr_out_len, "CHAP_R=0x%s",
418407
response);
419408
*nr_out_len += 1;

0 commit comments

Comments
 (0)