hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/scsi/ses.c
....@@ -433,8 +433,8 @@
433433 }
434434 #endif /* 0 */
435435
436
-static void ses_process_descriptor(struct enclosure_component *ecomp,
437
- unsigned char *desc)
436
+static int ses_process_descriptor(struct enclosure_component *ecomp,
437
+ unsigned char *desc, int max_desc_len)
438438 {
439439 int eip = desc[0] & 0x10;
440440 int invalid = desc[0] & 0x80;
....@@ -445,22 +445,32 @@
445445 unsigned char *d;
446446
447447 if (invalid)
448
- return;
448
+ return 0;
449449
450450 switch (proto) {
451451 case SCSI_PROTOCOL_FCP:
452452 if (eip) {
453
+ if (max_desc_len <= 7)
454
+ return 1;
453455 d = desc + 4;
454456 slot = d[3];
455457 }
456458 break;
457459 case SCSI_PROTOCOL_SAS:
460
+
458461 if (eip) {
462
+ if (max_desc_len <= 27)
463
+ return 1;
459464 d = desc + 4;
460465 slot = d[3];
461466 d = desc + 8;
462
- } else
467
+ } else {
468
+ if (max_desc_len <= 23)
469
+ return 1;
463470 d = desc + 4;
471
+ }
472
+
473
+
464474 /* only take the phy0 addr */
465475 addr = (u64)d[12] << 56 |
466476 (u64)d[13] << 48 |
....@@ -477,6 +487,8 @@
477487 }
478488 ecomp->slot = slot;
479489 scomp->addr = addr;
490
+
491
+ return 0;
480492 }
481493
482494 struct efd {
....@@ -490,9 +502,6 @@
490502 struct efd *efd = data;
491503 int i;
492504 struct ses_component *scomp;
493
-
494
- if (!edev->component[0].scratch)
495
- return 0;
496505
497506 for (i = 0; i < edev->components; i++) {
498507 scomp = edev->component[i].scratch;
....@@ -549,7 +558,7 @@
549558 /* skip past overall descriptor */
550559 desc_ptr += len + 4;
551560 }
552
- if (ses_dev->page10)
561
+ if (ses_dev->page10 && ses_dev->page10_len > 9)
553562 addl_desc_ptr = ses_dev->page10 + 8;
554563 type_ptr = ses_dev->page1_types;
555564 components = 0;
....@@ -557,17 +566,22 @@
557566 for (j = 0; j < type_ptr[1]; j++) {
558567 char *name = NULL;
559568 struct enclosure_component *ecomp;
569
+ int max_desc_len;
560570
561571 if (desc_ptr) {
562
- if (desc_ptr >= buf + page7_len) {
572
+ if (desc_ptr + 3 >= buf + page7_len) {
563573 desc_ptr = NULL;
564574 } else {
565575 len = (desc_ptr[2] << 8) + desc_ptr[3];
566576 desc_ptr += 4;
567
- /* Add trailing zero - pushes into
568
- * reserved space */
569
- desc_ptr[len] = '\0';
570
- name = desc_ptr;
577
+ if (desc_ptr + len > buf + page7_len)
578
+ desc_ptr = NULL;
579
+ else {
580
+ /* Add trailing zero - pushes into
581
+ * reserved space */
582
+ desc_ptr[len] = '\0';
583
+ name = desc_ptr;
584
+ }
571585 }
572586 }
573587 if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
....@@ -579,14 +593,20 @@
579593 components++,
580594 type_ptr[0],
581595 name);
582
- else
596
+ else if (components < edev->components)
583597 ecomp = &edev->component[components++];
598
+ else
599
+ ecomp = ERR_PTR(-EINVAL);
584600
585601 if (!IS_ERR(ecomp)) {
586
- if (addl_desc_ptr)
587
- ses_process_descriptor(
588
- ecomp,
589
- addl_desc_ptr);
602
+ if (addl_desc_ptr) {
603
+ max_desc_len = ses_dev->page10_len -
604
+ (addl_desc_ptr - ses_dev->page10);
605
+ if (ses_process_descriptor(ecomp,
606
+ addl_desc_ptr,
607
+ max_desc_len))
608
+ addl_desc_ptr = NULL;
609
+ }
590610 if (create)
591611 enclosure_component_register(
592612 ecomp);
....@@ -603,9 +623,11 @@
603623 /* these elements are optional */
604624 type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
605625 type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
606
- type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
626
+ type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) {
607627 addl_desc_ptr += addl_desc_ptr[1] + 2;
608
-
628
+ if (addl_desc_ptr + 1 >= ses_dev->page10 + ses_dev->page10_len)
629
+ addl_desc_ptr = NULL;
630
+ }
609631 }
610632 }
611633 kfree(buf);
....@@ -704,6 +726,7 @@
704726 type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE)
705727 components += type_ptr[1];
706728 }
729
+
707730 ses_dev->page1 = buf;
708731 ses_dev->page1_len = len;
709732 buf = NULL;
....@@ -745,9 +768,11 @@
745768 buf = NULL;
746769 }
747770 page2_not_supported:
748
- scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL);
749
- if (!scomp)
750
- goto err_free;
771
+ if (components > 0) {
772
+ scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL);
773
+ if (!scomp)
774
+ goto err_free;
775
+ }
751776
752777 edev = enclosure_register(cdev->parent, dev_name(&sdev->sdev_gendev),
753778 components, &ses_enclosure_callbacks);
....@@ -827,7 +852,8 @@
827852 kfree(ses_dev->page2);
828853 kfree(ses_dev);
829854
830
- kfree(edev->component[0].scratch);
855
+ if (edev->components)
856
+ kfree(edev->component[0].scratch);
831857
832858 put_device(&edev->edev);
833859 enclosure_unregister(edev);