Skip to content

Commit 8c052a5

Browse files
plugins/ocp: Prevent Seg Fault during Telemetry log Parsing
Invalid length values in the OCP DA 1 and 2 Telemetry Event FIFO entries caused the OCP internal-log command to seg fault. This commit will add checks for invalid lengths and abort the parsing if found. Signed-off-by: jeff-lien-sndk <[email protected]> Reviewed-by: brandon-paupore-sndk <[email protected]>
1 parent bcf72cf commit 8c052a5

3 files changed

Lines changed: 79 additions & 57 deletions

File tree

plugins/ocp/ocp-nvme.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#if !defined(OCP_NVME) || defined(CMD_HEADER_MULTI_READ)
1212
#define OCP_NVME
1313

14-
#define OCP_PLUGIN_VERSION "2.15.3"
14+
#define OCP_PLUGIN_VERSION "2.16.0"
1515
#include "cmd.h"
1616

1717
PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),

plugins/ocp/ocp-telemetry-decode.c

Lines changed: 58 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,10 @@ int parse_ocp_telemetry_string_log(int event_fifo_num, int identifier, int debug
674674
}
675675

676676
#ifdef CONFIG_JSONC
677-
void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
678-
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
679-
struct json_object *pevent_fifos_object, FILE *fp)
677+
int parse_time_stamp_event(
678+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
679+
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
680+
struct json_object *pevent_fifos_object, FILE *fp)
680681
{
681682
struct nvme_ocp_time_stamp_dbg_evt_class_format *ptime_stamp_event =
682683
(struct nvme_ocp_time_stamp_dbg_evt_class_format *) pevent_specific_data;
@@ -704,7 +705,8 @@ void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
704705
parse_ocp_telemetry_string_log(0, vu_event_id,
705706
pevent_descriptor->debug_event_class_type,
706707
VU_EVENT_STRING, description_str);
707-
}
708+
} else if (pevent_descriptor->event_data_size < 2)
709+
return -1;
708710

709711
if (pevent_fifos_object != NULL) {
710712
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -736,11 +738,14 @@ void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
736738
}
737739
}
738740
}
741+
742+
return 0;
739743
}
740744

741-
void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
742-
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
743-
struct json_object *pevent_fifos_object, FILE *fp)
745+
int parse_pcie_event(
746+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
747+
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
748+
struct json_object *pevent_fifos_object, FILE *fp)
744749
{
745750
struct nvme_ocp_pcie_dbg_evt_class_format *ppcie_event =
746751
(struct nvme_ocp_pcie_dbg_evt_class_format *) pevent_specific_data;
@@ -768,7 +773,8 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
768773
parse_ocp_telemetry_string_log(0, vu_event_id,
769774
pevent_descriptor->debug_event_class_type,
770775
VU_EVENT_STRING, description_str);
771-
}
776+
} else if (pevent_descriptor->event_data_size < 1)
777+
return -1;
772778

773779
if (pevent_fifos_object != NULL) {
774780
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -800,11 +806,14 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
800806
}
801807
}
802808
}
809+
810+
return 0;
803811
}
804812

805-
void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
806-
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
807-
struct json_object *pevent_fifos_object, FILE *fp)
813+
int parse_nvme_event(
814+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
815+
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
816+
struct json_object *pevent_fifos_object, FILE *fp)
808817
{
809818
struct nvme_ocp_nvme_dbg_evt_class_format *pnvme_event =
810819
(struct nvme_ocp_nvme_dbg_evt_class_format *) pevent_specific_data;
@@ -833,7 +842,8 @@ void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
833842
pevent_descriptor->debug_event_class_type,
834843
VU_EVENT_STRING,
835844
description_str);
836-
}
845+
} else if (pevent_descriptor->event_data_size < 2)
846+
return -1;
837847

838848
if (pevent_fifos_object != NULL) {
839849
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -865,6 +875,8 @@ void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
865875
}
866876
}
867877
}
878+
879+
return 0;
868880
}
869881

870882
void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
@@ -907,9 +919,10 @@ void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descr
907919
}
908920
}
909921

910-
void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
911-
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
912-
struct json_object *pevent_fifos_object, FILE *fp)
922+
int parse_media_wear_event(
923+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
924+
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
925+
struct json_object *pevent_fifos_object, FILE *fp)
913926
{
914927
struct nvme_ocp_media_wear_dbg_evt_class_format *pmedia_wear_event =
915928
(struct nvme_ocp_media_wear_dbg_evt_class_format *) pevent_specific_data;
@@ -939,7 +952,8 @@ void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
939952
pevent_descriptor->debug_event_class_type,
940953
VU_EVENT_STRING,
941954
description_str);
942-
}
955+
} else if (pevent_descriptor->event_data_size < 3)
956+
return -1;
943957

944958
if (pevent_fifos_object != NULL) {
945959
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -971,6 +985,8 @@ void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
971985
}
972986
}
973987
}
988+
989+
return 0;
974990
}
975991

976992
int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
@@ -982,7 +998,7 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
982998
return -1;
983999
}
9841000

985-
int status = 0;
1001+
int status = 0, ret = 0;
9861002
unsigned int event_fifo_number = fifo_num + 1;
9871003
char *description = (char *)malloc((40 + 1) * sizeof(char));
9881004

@@ -1095,21 +1111,21 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
10951111

10961112
switch (pevent_descriptor->debug_event_class_type) {
10971113
case TIME_STAMP_CLASS_TYPE:
1098-
parse_time_stamp_event(pevent_descriptor,
1114+
ret = parse_time_stamp_event(pevent_descriptor,
10991115
pevent_descriptor_obj,
11001116
pevent_specific_data,
11011117
pevent_fifos_object,
11021118
fp);
11031119
break;
11041120
case PCIE_CLASS_TYPE:
1105-
parse_pcie_event(pevent_descriptor,
1121+
ret = parse_pcie_event(pevent_descriptor,
11061122
pevent_descriptor_obj,
11071123
pevent_specific_data,
11081124
pevent_fifos_object,
11091125
fp);
11101126
break;
11111127
case NVME_CLASS_TYPE:
1112-
parse_nvme_event(pevent_descriptor,
1128+
ret = parse_nvme_event(pevent_descriptor,
11131129
pevent_descriptor_obj,
11141130
pevent_specific_data,
11151131
pevent_fifos_object,
@@ -1125,9 +1141,10 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
11251141
pevent_specific_data,
11261142
pevent_fifos_object,
11271143
fp);
1144+
ret = 0;
11281145
break;
11291146
case MEDIA_WEAR_CLASS_TYPE:
1130-
parse_media_wear_event(pevent_descriptor,
1147+
ret = parse_media_wear_event(pevent_descriptor,
11311148
pevent_descriptor_obj,
11321149
pevent_specific_data,
11331150
pevent_fifos_object,
@@ -1138,6 +1155,18 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
11381155
break;
11391156
}
11401157

1158+
if (ret) {
1159+
fprintf(stderr, "ERROR : OCP : Invalid NVMe Event FIFO "
1160+
"entry. FIFO: %d, offset: 0x%x\n",
1161+
fifo_num, offset_to_move);
1162+
fprintf(stderr, "ERROR : OCP : Type: 0x%02x, ID: 0x%04x,"
1163+
" Size: 0x%02x\n",
1164+
pevent_descriptor->debug_event_class_type,
1165+
pevent_descriptor->event_id,
1166+
pevent_descriptor->event_data_size);
1167+
goto free_desc;
1168+
}
1169+
11411170
if (pevent_descriptor_obj != NULL && pevent_fifo_array != NULL)
11421171
json_array_add_value_object(pevent_fifo_array,
11431172
pevent_descriptor_obj);
@@ -1214,8 +1243,9 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
12141243
json_object_add_value_array(pevent_fifos_object, event_fifo_name,
12151244
pevent_fifo_array);
12161245

1246+
free_desc:
12171247
free(description);
1218-
return 0;
1248+
return ret;
12191249
}
12201250

12211251
int parse_event_fifos(struct json_object *root, struct nvme_ocp_telemetry_offsets *poffsets,
@@ -1610,10 +1640,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
16101640
fprintf(fp, "%s\n", STR_DA_1_EVENT_FIFO_INFO);
16111641
fprintf(fp, STR_LINE);
16121642
status = parse_event_fifos(NULL, &offsets, fp);
1613-
if (status != 0) {
1614-
nvme_show_error("status: %d\n", status);
1643+
if (status != 0)
16151644
return -1;
1616-
}
16171645

16181646
//Set the DA to 2
16191647
if (options->data_area == 2) {
@@ -1632,10 +1660,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
16321660
fprintf(fp, "%s\n", STR_DA_2_EVENT_FIFO_INFO);
16331661
fprintf(fp, STR_LINE);
16341662
status = parse_event_fifos(NULL, &offsets, fp);
1635-
if (status != 0) {
1636-
nvme_show_error("status: %d\n", status);
1663+
if (status != 0)
16371664
return -1;
1638-
}
16391665
}
16401666

16411667
fprintf(fp, STR_LINE);
@@ -1719,10 +1745,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
17191745
printf("%s\n", STR_DA_1_EVENT_FIFO_INFO);
17201746
printf(STR_LINE);
17211747
status = parse_event_fifos(NULL, &offsets, NULL);
1722-
if (status != 0) {
1723-
nvme_show_error("status: %d\n", status);
1748+
if (status != 0)
17241749
return -1;
1725-
}
17261750

17271751
//Set the DA to 2
17281752
if (options->data_area == 2) {
@@ -1740,10 +1764,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
17401764
printf("%s\n", STR_DA_2_EVENT_FIFO_INFO);
17411765
printf(STR_LINE);
17421766
status = parse_event_fifos(NULL, &offsets, NULL);
1743-
if (status != 0) {
1744-
nvme_show_error("status: %d\n", status);
1767+
if (status != 0)
17451768
return -1;
1746-
}
17471769
}
17481770

17491771
printf(STR_LINE);
@@ -1826,10 +1848,8 @@ int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
18261848

18271849
//Data Area 1 Event FIFOs
18281850
status = parse_event_fifos(root, &offsets, NULL);
1829-
if (status != 0) {
1830-
nvme_show_error("status: %d\n", status, NULL);
1851+
if (status != 0)
18311852
return -1;
1832-
}
18331853

18341854
if (options->data_area == 2) {
18351855
//Set the DA to 2
@@ -1843,10 +1863,8 @@ int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
18431863

18441864
//Data Area 2 Event FIFOs
18451865
status = parse_event_fifos(root, &offsets, NULL);
1846-
if (status != 0) {
1847-
nvme_show_error("status: %d\n", status);
1866+
if (status != 0)
18481867
return -1;
1849-
}
18501868
}
18511869

18521870
if (options->output_file != NULL) {

plugins/ocp/ocp-telemetry-decode.h

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,11 +1389,12 @@ int get_vu_event_id_ascii_string(int identifier, int debug_event_class, char *de
13891389
* @param pevent_fifos_object, event fifos json object pointer
13901390
* @param fp, input file pointer
13911391
*
1392-
* @return
1392+
* @return 0 success
13931393
*/
1394-
void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1395-
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
1396-
struct json_object *pevent_fifos_object, FILE *fp);
1394+
int parse_time_stamp_event(
1395+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1396+
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
1397+
struct json_object *pevent_fifos_object, FILE *fp);
13971398

13981399
/**
13991400
* @brief parses a pcie event fifo data to text or json formats
@@ -1404,11 +1405,12 @@ void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
14041405
* @param pevent_fifos_object, event fifos json object pointer
14051406
* @param fp, input file pointer
14061407
*
1407-
* @return
1408+
* @return 0 success
14081409
*/
1409-
void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1410-
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
1411-
struct json_object *pevent_fifos_object, FILE *fp);
1410+
int parse_pcie_event(
1411+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1412+
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
1413+
struct json_object *pevent_fifos_object, FILE *fp);
14121414

14131415
/**
14141416
* @brief parses a nvme event fifo data to text or json formats
@@ -1419,11 +1421,12 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
14191421
* @param pevent_fifos_object, event fifos json object pointer
14201422
* @param fp, input file pointer
14211423
*
1422-
* @return
1424+
* @return 0 success
14231425
*/
1424-
void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1425-
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
1426-
struct json_object *pevent_fifos_object, FILE *fp);
1426+
int parse_nvme_event(
1427+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1428+
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
1429+
struct json_object *pevent_fifos_object, FILE *fp);
14271430

14281431
/**
14291432
* @brief parses common event fifo data to text or json formats
@@ -1449,9 +1452,10 @@ void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descr
14491452
* @param pevent_fifos_object, event fifos json object pointer
14501453
* @param fp, input file pointer
14511454
*
1452-
* @return
1455+
* @return 0 success
14531456
*/
1454-
void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1455-
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
1456-
struct json_object *pevent_fifos_object, FILE *fp);
1457+
int parse_media_wear_event(
1458+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1459+
struct json_object *pevent_descriptor_obj, __u8 *pevent_specific_data,
1460+
struct json_object *pevent_fifos_object, FILE *fp);
14571461
#endif /* OCP_TELEMETRY_DECODE_H */

0 commit comments

Comments
 (0)