aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-25 12:14:14 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-25 12:14:14 -0400
commit846e8dd47c264e0b359afed28ea88e0acdee6818 (patch)
tree174756b312f282b06cdb9e9e0317a81756e71e89
parentbfb0e9b490bc15f243009359745a9d8a94089dc4 (diff)
parentf1f1fadacaf08b7cf11714c0c29f8fa4d4ef68a9 (diff)
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
-rw-r--r--drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c5
-rw-r--r--drivers/scsi/ipr.c106
-rw-r--r--drivers/scsi/ipr.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c15
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c10
-rw-r--r--drivers/scsi/lpfc/lpfc_nvme.c11
-rw-r--r--drivers/scsi/sd.c6
-rw-r--r--drivers/scsi/ufs/ufshcd.c7
-rw-r--r--drivers/target/iscsi/iscsi_target_auth.c45
9 files changed, 116 insertions, 90 deletions
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index fac377320158..f42a619198c4 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -3474,11 +3474,10 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
3474 vscsi->dds.window[LOCAL].liobn, 3474 vscsi->dds.window[LOCAL].liobn,
3475 vscsi->dds.window[REMOTE].liobn); 3475 vscsi->dds.window[REMOTE].liobn);
3476 3476
3477 strcpy(vscsi->eye, "VSCSI "); 3477 snprintf(vscsi->eye, sizeof(vscsi->eye), "VSCSI %s", vdev->name);
3478 strncat(vscsi->eye, vdev->name, MAX_EYE);
3479 3478
3480 vscsi->dds.unit_id = vdev->unit_address; 3479 vscsi->dds.unit_id = vdev->unit_address;
3481 strncpy(vscsi->dds.partition_name, partition_name, 3480 strscpy(vscsi->dds.partition_name, partition_name,
3482 sizeof(vscsi->dds.partition_name)); 3481 sizeof(vscsi->dds.partition_name));
3483 vscsi->dds.partition_num = partition_number; 3482 vscsi->dds.partition_num = partition_number;
3484 3483
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index f2ec80b0ffc0..271990bc065b 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3335,6 +3335,65 @@ static void ipr_release_dump(struct kref *kref)
3335 LEAVE; 3335 LEAVE;
3336} 3336}
3337 3337
3338static 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
3351restart:
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
3338/** 3397/**
3339 * ipr_worker_thread - Worker thread 3398 * ipr_worker_thread - Worker thread
3340 * @work: ioa config struct 3399 * @work: ioa config struct
@@ -3349,13 +3408,9 @@ static void ipr_release_dump(struct kref *kref)
3349static void ipr_worker_thread(struct work_struct *work) 3408static void ipr_worker_thread(struct work_struct *work)
3350{ 3409{
3351 unsigned long lock_flags; 3410 unsigned long lock_flags;
3352 struct ipr_resource_entry *res;
3353 struct scsi_device *sdev;
3354 struct ipr_dump *dump; 3411 struct ipr_dump *dump;
3355 struct ipr_ioa_cfg *ioa_cfg = 3412 struct ipr_ioa_cfg *ioa_cfg =
3356 container_of(work, struct ipr_ioa_cfg, work_q); 3413 container_of(work, struct ipr_ioa_cfg, work_q);
3357 u8 bus, target, lun;
3358 int did_work;
3359 3414
3360 ENTER; 3415 ENTER;
3361 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); 3416 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -3393,49 +3448,9 @@ static void ipr_worker_thread(struct work_struct *work)
3393 return; 3448 return;
3394 } 3449 }
3395 3450
3396restart: 3451 schedule_work(&ioa_cfg->scsi_add_work_q);
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 }
3403 3452
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;
3437 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3453 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3438 kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
3439 LEAVE; 3454 LEAVE;
3440} 3455}
3441 3456
@@ -9933,6 +9948,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
9933 INIT_LIST_HEAD(&ioa_cfg->free_res_q); 9948 INIT_LIST_HEAD(&ioa_cfg->free_res_q);
9934 INIT_LIST_HEAD(&ioa_cfg->used_res_q); 9949 INIT_LIST_HEAD(&ioa_cfg->used_res_q);
9935 INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread); 9950 INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread);
9951 INIT_WORK(&ioa_cfg->scsi_add_work_q, ipr_add_remove_thread);
9936 init_waitqueue_head(&ioa_cfg->reset_wait_q); 9952 init_waitqueue_head(&ioa_cfg->reset_wait_q);
9937 init_waitqueue_head(&ioa_cfg->msi_wait_q); 9953 init_waitqueue_head(&ioa_cfg->msi_wait_q);
9938 init_waitqueue_head(&ioa_cfg->eeh_wait_q); 9954 init_waitqueue_head(&ioa_cfg->eeh_wait_q);
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 68afbbde54d3..f6baa2351313 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1575,6 +1575,7 @@ struct ipr_ioa_cfg {
1575 u8 saved_mode_page_len; 1575 u8 saved_mode_page_len;
1576 1576
1577 struct work_struct work_q; 1577 struct work_struct work_q;
1578 struct work_struct scsi_add_work_q;
1578 struct workqueue_struct *reset_work_q; 1579 struct workqueue_struct *reset_work_q;
1579 1580
1580 wait_queue_head_t reset_wait_q; 1581 wait_queue_head_t reset_wait_q;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 057a60abe664..1a6ed9b0a249 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -360,12 +360,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
360 goto buffer_done; 360 goto buffer_done;
361 361
362 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 362 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
363 nrport = NULL;
364 spin_lock(&vport->phba->hbalock);
363 rport = lpfc_ndlp_get_nrport(ndlp); 365 rport = lpfc_ndlp_get_nrport(ndlp);
364 if (!rport) 366 if (rport)
365 continue; 367 nrport = rport->remoteport;
366 368 spin_unlock(&vport->phba->hbalock);
367 /* local short-hand pointer. */
368 nrport = rport->remoteport;
369 if (!nrport) 369 if (!nrport)
370 continue; 370 continue;
371 371
@@ -3386,6 +3386,7 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
3386 struct lpfc_nodelist *ndlp; 3386 struct lpfc_nodelist *ndlp;
3387#if (IS_ENABLED(CONFIG_NVME_FC)) 3387#if (IS_ENABLED(CONFIG_NVME_FC))
3388 struct lpfc_nvme_rport *rport; 3388 struct lpfc_nvme_rport *rport;
3389 struct nvme_fc_remote_port *remoteport = NULL;
3389#endif 3390#endif
3390 3391
3391 shost = lpfc_shost_from_vport(vport); 3392 shost = lpfc_shost_from_vport(vport);
@@ -3396,8 +3397,12 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
3396 if (ndlp->rport) 3397 if (ndlp->rport)
3397 ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo; 3398 ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
3398#if (IS_ENABLED(CONFIG_NVME_FC)) 3399#if (IS_ENABLED(CONFIG_NVME_FC))
3400 spin_lock(&vport->phba->hbalock);
3399 rport = lpfc_ndlp_get_nrport(ndlp); 3401 rport = lpfc_ndlp_get_nrport(ndlp);
3400 if (rport) 3402 if (rport)
3403 remoteport = rport->remoteport;
3404 spin_unlock(&vport->phba->hbalock);
3405 if (remoteport)
3401 nvme_fc_set_remoteport_devloss(rport->remoteport, 3406 nvme_fc_set_remoteport_devloss(rport->remoteport,
3402 vport->cfg_devloss_tmo); 3407 vport->cfg_devloss_tmo);
3403#endif 3408#endif
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 9df0c051349f..aec5b10a8c85 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -551,7 +551,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
551 unsigned char *statep; 551 unsigned char *statep;
552 struct nvme_fc_local_port *localport; 552 struct nvme_fc_local_port *localport;
553 struct lpfc_nvmet_tgtport *tgtp; 553 struct lpfc_nvmet_tgtport *tgtp;
554 struct nvme_fc_remote_port *nrport; 554 struct nvme_fc_remote_port *nrport = NULL;
555 struct lpfc_nvme_rport *rport; 555 struct lpfc_nvme_rport *rport;
556 556
557 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE); 557 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
@@ -696,11 +696,11 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
696 len += snprintf(buf + len, size - len, "\tRport List:\n"); 696 len += snprintf(buf + len, size - len, "\tRport List:\n");
697 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 697 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
698 /* local short-hand pointer. */ 698 /* local short-hand pointer. */
699 spin_lock(&phba->hbalock);
699 rport = lpfc_ndlp_get_nrport(ndlp); 700 rport = lpfc_ndlp_get_nrport(ndlp);
700 if (!rport) 701 if (rport)
701 continue; 702 nrport = rport->remoteport;
702 703 spin_unlock(&phba->hbalock);
703 nrport = rport->remoteport;
704 if (!nrport) 704 if (!nrport)
705 continue; 705 continue;
706 706
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 028462e5994d..918ae18ef8a8 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -2725,7 +2725,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2725 rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn); 2725 rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
2726 rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); 2726 rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
2727 2727
2728 spin_lock_irq(&vport->phba->hbalock);
2728 oldrport = lpfc_ndlp_get_nrport(ndlp); 2729 oldrport = lpfc_ndlp_get_nrport(ndlp);
2730 spin_unlock_irq(&vport->phba->hbalock);
2729 if (!oldrport) 2731 if (!oldrport)
2730 lpfc_nlp_get(ndlp); 2732 lpfc_nlp_get(ndlp);
2731 2733
@@ -2840,7 +2842,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2840 struct nvme_fc_local_port *localport; 2842 struct nvme_fc_local_port *localport;
2841 struct lpfc_nvme_lport *lport; 2843 struct lpfc_nvme_lport *lport;
2842 struct lpfc_nvme_rport *rport; 2844 struct lpfc_nvme_rport *rport;
2843 struct nvme_fc_remote_port *remoteport; 2845 struct nvme_fc_remote_port *remoteport = NULL;
2844 2846
2845 localport = vport->localport; 2847 localport = vport->localport;
2846 2848
@@ -2854,11 +2856,14 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2854 if (!lport) 2856 if (!lport)
2855 goto input_err; 2857 goto input_err;
2856 2858
2859 spin_lock_irq(&vport->phba->hbalock);
2857 rport = lpfc_ndlp_get_nrport(ndlp); 2860 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)
2859 goto input_err; 2865 goto input_err;
2860 2866
2861 remoteport = rport->remoteport;
2862 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, 2867 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
2863 "6033 Unreg nvme remoteport %p, portname x%llx, " 2868 "6033 Unreg nvme remoteport %p, portname x%llx, "
2864 "port_id x%06x, portstate x%x port type x%x\n", 2869 "port_id x%06x, portstate x%x port type x%x\n",
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b79b366a94f7..4a57ffecc7e6 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1276,7 +1276,8 @@ static int sd_init_command(struct scsi_cmnd *cmd)
1276 case REQ_OP_ZONE_RESET: 1276 case REQ_OP_ZONE_RESET:
1277 return sd_zbc_setup_reset_cmnd(cmd); 1277 return sd_zbc_setup_reset_cmnd(cmd);
1278 default: 1278 default:
1279 BUG(); 1279 WARN_ON_ONCE(1);
1280 return BLKPREP_KILL;
1280 } 1281 }
1281} 1282}
1282 1283
@@ -2959,6 +2960,9 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
2959 if (rot == 1) { 2960 if (rot == 1) {
2960 blk_queue_flag_set(QUEUE_FLAG_NONROT, q); 2961 blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
2961 blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q); 2962 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);
2962 } 2966 }
2963 2967
2964 if (sdkp->device->type == TYPE_ZBC) { 2968 if (sdkp->device->type == TYPE_ZBC) {
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 9d5d2ca7fc4f..c55f38ec391c 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7940,6 +7940,13 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
7940 err = -ENOMEM; 7940 err = -ENOMEM;
7941 goto out_error; 7941 goto out_error;
7942 } 7942 }
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
7943 hba = shost_priv(host); 7950 hba = shost_priv(host);
7944 hba->host = host; 7951 hba->host = host;
7945 hba->dev = dev; 7952 hba->dev = dev;
diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c
index 9518ffd8b8ba..4e680d753941 100644
--- a/drivers/target/iscsi/iscsi_target_auth.c
+++ b/drivers/target/iscsi/iscsi_target_auth.c
@@ -26,27 +26,6 @@
26#include "iscsi_target_nego.h" 26#include "iscsi_target_nego.h"
27#include "iscsi_target_auth.h" 27#include "iscsi_target_auth.h"
28 28
29static 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
41static 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
50static int chap_gen_challenge( 29static int chap_gen_challenge(
51 struct iscsi_conn *conn, 30 struct iscsi_conn *conn,
52 int caller, 31 int caller,
@@ -62,7 +41,7 @@ static int chap_gen_challenge(
62 ret = get_random_bytes_wait(chap->challenge, CHAP_CHALLENGE_LENGTH); 41 ret = get_random_bytes_wait(chap->challenge, CHAP_CHALLENGE_LENGTH);
63 if (unlikely(ret)) 42 if (unlikely(ret))
64 return ret; 43 return ret;
65 chap_binaryhex_to_asciihex(challenge_asciihex, chap->challenge, 44 bin2hex(challenge_asciihex, chap->challenge,
66 CHAP_CHALLENGE_LENGTH); 45 CHAP_CHALLENGE_LENGTH);
67 /* 46 /*
68 * Set CHAP_C, and copy the generated challenge into c_str. 47 * Set CHAP_C, and copy the generated challenge into c_str.
@@ -248,9 +227,16 @@ static int chap_server_compute_md5(
248 pr_err("Could not find CHAP_R.\n"); 227 pr_err("Could not find CHAP_R.\n");
249 goto out; 228 goto out;
250 } 229 }
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 }
251 238
252 pr_debug("[server] Got CHAP_R=%s\n", chap_r); 239 pr_debug("[server] Got CHAP_R=%s\n", chap_r);
253 chap_string_to_hex(client_digest, chap_r, strlen(chap_r));
254 240
255 tfm = crypto_alloc_shash("md5", 0, 0); 241 tfm = crypto_alloc_shash("md5", 0, 0);
256 if (IS_ERR(tfm)) { 242 if (IS_ERR(tfm)) {
@@ -294,7 +280,7 @@ static int chap_server_compute_md5(
294 goto out; 280 goto out;
295 } 281 }
296 282
297 chap_binaryhex_to_asciihex(response, server_digest, MD5_SIGNATURE_SIZE); 283 bin2hex(response, server_digest, MD5_SIGNATURE_SIZE);
298 pr_debug("[server] MD5 Server Digest: %s\n", response); 284 pr_debug("[server] MD5 Server Digest: %s\n", response);
299 285
300 if (memcmp(server_digest, client_digest, MD5_SIGNATURE_SIZE) != 0) { 286 if (memcmp(server_digest, client_digest, MD5_SIGNATURE_SIZE) != 0) {
@@ -349,9 +335,7 @@ static int chap_server_compute_md5(
349 pr_err("Could not find CHAP_C.\n"); 335 pr_err("Could not find CHAP_C.\n");
350 goto out; 336 goto out;
351 } 337 }
352 pr_debug("[server] Got CHAP_C=%s\n", challenge); 338 challenge_len = DIV_ROUND_UP(strlen(challenge), 2);
353 challenge_len = chap_string_to_hex(challenge_binhex, challenge,
354 strlen(challenge));
355 if (!challenge_len) { 339 if (!challenge_len) {
356 pr_err("Unable to convert incoming challenge\n"); 340 pr_err("Unable to convert incoming challenge\n");
357 goto out; 341 goto out;
@@ -360,6 +344,11 @@ static int chap_server_compute_md5(
360 pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n"); 344 pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
361 goto out; 345 goto out;
362 } 346 }
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);
363 /* 352 /*
364 * During mutual authentication, the CHAP_C generated by the 353 * During mutual authentication, the CHAP_C generated by the
365 * initiator must not match the original CHAP_C generated by 354 * initiator must not match the original CHAP_C generated by
@@ -413,7 +402,7 @@ static int chap_server_compute_md5(
413 /* 402 /*
414 * Convert response from binary hex to ascii hext. 403 * Convert response from binary hex to ascii hext.
415 */ 404 */
416 chap_binaryhex_to_asciihex(response, digest, MD5_SIGNATURE_SIZE); 405 bin2hex(response, digest, MD5_SIGNATURE_SIZE);
417 *nr_out_len += sprintf(nr_out_ptr + *nr_out_len, "CHAP_R=0x%s", 406 *nr_out_len += sprintf(nr_out_ptr + *nr_out_len, "CHAP_R=0x%s",
418 response); 407 response);
419 *nr_out_len += 1; 408 *nr_out_len += 1;