Skip to content

Commit 3c54948

Browse files
jeff-lien-sndkigaw
authored andcommitted
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 3c54948

File tree

3 files changed

+97
-57
lines changed

3 files changed

+97
-57
lines changed

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: 68 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,12 @@ 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,
680+
__u8 *pevent_specific_data,
681+
struct json_object *pevent_fifos_object,
682+
FILE *fp)
680683
{
681684
struct nvme_ocp_time_stamp_dbg_evt_class_format *ptime_stamp_event =
682685
(struct nvme_ocp_time_stamp_dbg_evt_class_format *) pevent_specific_data;
@@ -704,7 +707,8 @@ void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
704707
parse_ocp_telemetry_string_log(0, vu_event_id,
705708
pevent_descriptor->debug_event_class_type,
706709
VU_EVENT_STRING, description_str);
707-
}
710+
} else if (pevent_descriptor->event_data_size < 2)
711+
return -1;
708712

709713
if (pevent_fifos_object != NULL) {
710714
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -736,11 +740,16 @@ void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
736740
}
737741
}
738742
}
743+
744+
return 0;
739745
}
740746

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)
747+
int parse_pcie_event(
748+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
749+
struct json_object *pevent_descriptor_obj,
750+
__u8 *pevent_specific_data,
751+
struct json_object *pevent_fifos_object,
752+
FILE *fp)
744753
{
745754
struct nvme_ocp_pcie_dbg_evt_class_format *ppcie_event =
746755
(struct nvme_ocp_pcie_dbg_evt_class_format *) pevent_specific_data;
@@ -768,7 +777,8 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
768777
parse_ocp_telemetry_string_log(0, vu_event_id,
769778
pevent_descriptor->debug_event_class_type,
770779
VU_EVENT_STRING, description_str);
771-
}
780+
} else if (pevent_descriptor->event_data_size < 1)
781+
return -1;
772782

773783
if (pevent_fifos_object != NULL) {
774784
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -800,11 +810,16 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
800810
}
801811
}
802812
}
813+
814+
return 0;
803815
}
804816

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)
817+
int parse_nvme_event(
818+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
819+
struct json_object *pevent_descriptor_obj,
820+
__u8 *pevent_specific_data,
821+
struct json_object *pevent_fifos_object,
822+
FILE *fp)
808823
{
809824
struct nvme_ocp_nvme_dbg_evt_class_format *pnvme_event =
810825
(struct nvme_ocp_nvme_dbg_evt_class_format *) pevent_specific_data;
@@ -833,7 +848,8 @@ void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
833848
pevent_descriptor->debug_event_class_type,
834849
VU_EVENT_STRING,
835850
description_str);
836-
}
851+
} else if (pevent_descriptor->event_data_size < 2)
852+
return -1;
837853

838854
if (pevent_fifos_object != NULL) {
839855
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -865,6 +881,8 @@ void parse_nvme_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
865881
}
866882
}
867883
}
884+
885+
return 0;
868886
}
869887

870888
void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
@@ -907,9 +925,12 @@ void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descr
907925
}
908926
}
909927

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)
928+
int parse_media_wear_event(
929+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
930+
struct json_object *pevent_descriptor_obj,
931+
__u8 *pevent_specific_data,
932+
struct json_object *pevent_fifos_object,
933+
FILE *fp)
913934
{
914935
struct nvme_ocp_media_wear_dbg_evt_class_format *pmedia_wear_event =
915936
(struct nvme_ocp_media_wear_dbg_evt_class_format *) pevent_specific_data;
@@ -939,7 +960,8 @@ void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
939960
pevent_descriptor->debug_event_class_type,
940961
VU_EVENT_STRING,
941962
description_str);
942-
}
963+
} else if (pevent_descriptor->event_data_size < 3)
964+
return -1;
943965

944966
if (pevent_fifos_object != NULL) {
945967
json_add_formatted_var_size_str(pevent_descriptor_obj, STR_CLASS_SPECIFIC_DATA,
@@ -971,6 +993,8 @@ void parse_media_wear_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
971993
}
972994
}
973995
}
996+
997+
return 0;
974998
}
975999

9761000
int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
@@ -982,7 +1006,7 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
9821006
return -1;
9831007
}
9841008

985-
int status = 0;
1009+
int status = 0, ret = 0;
9861010
unsigned int event_fifo_number = fifo_num + 1;
9871011
char *description = (char *)malloc((40 + 1) * sizeof(char));
9881012

@@ -1095,21 +1119,21 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
10951119

10961120
switch (pevent_descriptor->debug_event_class_type) {
10971121
case TIME_STAMP_CLASS_TYPE:
1098-
parse_time_stamp_event(pevent_descriptor,
1122+
ret = parse_time_stamp_event(pevent_descriptor,
10991123
pevent_descriptor_obj,
11001124
pevent_specific_data,
11011125
pevent_fifos_object,
11021126
fp);
11031127
break;
11041128
case PCIE_CLASS_TYPE:
1105-
parse_pcie_event(pevent_descriptor,
1129+
ret = parse_pcie_event(pevent_descriptor,
11061130
pevent_descriptor_obj,
11071131
pevent_specific_data,
11081132
pevent_fifos_object,
11091133
fp);
11101134
break;
11111135
case NVME_CLASS_TYPE:
1112-
parse_nvme_event(pevent_descriptor,
1136+
ret = parse_nvme_event(pevent_descriptor,
11131137
pevent_descriptor_obj,
11141138
pevent_specific_data,
11151139
pevent_fifos_object,
@@ -1125,9 +1149,10 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
11251149
pevent_specific_data,
11261150
pevent_fifos_object,
11271151
fp);
1152+
ret = 0;
11281153
break;
11291154
case MEDIA_WEAR_CLASS_TYPE:
1130-
parse_media_wear_event(pevent_descriptor,
1155+
ret = parse_media_wear_event(pevent_descriptor,
11311156
pevent_descriptor_obj,
11321157
pevent_specific_data,
11331158
pevent_fifos_object,
@@ -1138,6 +1163,20 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
11381163
break;
11391164
}
11401165

1166+
if (ret) {
1167+
fprintf(stderr,
1168+
"ERROR : OCP : Invalid NVMe Event FIFO entry\n");
1169+
fprintf(stderr,
1170+
"FIFO: %d, offset: 0x%x\n",
1171+
fifo_num, offset_to_move);
1172+
fprintf(stderr,
1173+
"Type: 0x%x, ID: 0x%x, Size: 0x%x\n",
1174+
pevent_descriptor->debug_event_class_type,
1175+
pevent_descriptor->event_id,
1176+
pevent_descriptor->event_data_size);
1177+
goto free_desc;
1178+
}
1179+
11411180
if (pevent_descriptor_obj != NULL && pevent_fifo_array != NULL)
11421181
json_array_add_value_object(pevent_fifo_array,
11431182
pevent_descriptor_obj);
@@ -1214,8 +1253,9 @@ int parse_event_fifo(unsigned int fifo_num, unsigned char *pfifo_start,
12141253
json_object_add_value_array(pevent_fifos_object, event_fifo_name,
12151254
pevent_fifo_array);
12161255

1256+
free_desc:
12171257
free(description);
1218-
return 0;
1258+
return ret;
12191259
}
12201260

12211261
int parse_event_fifos(struct json_object *root, struct nvme_ocp_telemetry_offsets *poffsets,
@@ -1610,10 +1650,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
16101650
fprintf(fp, "%s\n", STR_DA_1_EVENT_FIFO_INFO);
16111651
fprintf(fp, STR_LINE);
16121652
status = parse_event_fifos(NULL, &offsets, fp);
1613-
if (status != 0) {
1614-
nvme_show_error("status: %d\n", status);
1653+
if (status != 0)
16151654
return -1;
1616-
}
16171655

16181656
//Set the DA to 2
16191657
if (options->data_area == 2) {
@@ -1632,10 +1670,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
16321670
fprintf(fp, "%s\n", STR_DA_2_EVENT_FIFO_INFO);
16331671
fprintf(fp, STR_LINE);
16341672
status = parse_event_fifos(NULL, &offsets, fp);
1635-
if (status != 0) {
1636-
nvme_show_error("status: %d\n", status);
1673+
if (status != 0)
16371674
return -1;
1638-
}
16391675
}
16401676

16411677
fprintf(fp, STR_LINE);
@@ -1719,10 +1755,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
17191755
printf("%s\n", STR_DA_1_EVENT_FIFO_INFO);
17201756
printf(STR_LINE);
17211757
status = parse_event_fifos(NULL, &offsets, NULL);
1722-
if (status != 0) {
1723-
nvme_show_error("status: %d\n", status);
1758+
if (status != 0)
17241759
return -1;
1725-
}
17261760

17271761
//Set the DA to 2
17281762
if (options->data_area == 2) {
@@ -1740,10 +1774,8 @@ int print_ocp_telemetry_normal(struct ocp_telemetry_parse_options *options)
17401774
printf("%s\n", STR_DA_2_EVENT_FIFO_INFO);
17411775
printf(STR_LINE);
17421776
status = parse_event_fifos(NULL, &offsets, NULL);
1743-
if (status != 0) {
1744-
nvme_show_error("status: %d\n", status);
1777+
if (status != 0)
17451778
return -1;
1746-
}
17471779
}
17481780

17491781
printf(STR_LINE);
@@ -1826,10 +1858,8 @@ int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
18261858

18271859
//Data Area 1 Event FIFOs
18281860
status = parse_event_fifos(root, &offsets, NULL);
1829-
if (status != 0) {
1830-
nvme_show_error("status: %d\n", status, NULL);
1861+
if (status != 0)
18311862
return -1;
1832-
}
18331863

18341864
if (options->data_area == 2) {
18351865
//Set the DA to 2
@@ -1843,10 +1873,8 @@ int print_ocp_telemetry_json(struct ocp_telemetry_parse_options *options)
18431873

18441874
//Data Area 2 Event FIFOs
18451875
status = parse_event_fifos(root, &offsets, NULL);
1846-
if (status != 0) {
1847-
nvme_show_error("status: %d\n", status);
1876+
if (status != 0)
18481877
return -1;
1849-
}
18501878
}
18511879

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

plugins/ocp/ocp-telemetry-decode.h

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,11 +1389,14 @@ 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,
1397+
__u8 *pevent_specific_data,
1398+
struct json_object *pevent_fifos_object,
1399+
FILE *fp);
13971400

13981401
/**
13991402
* @brief parses a pcie event fifo data to text or json formats
@@ -1404,11 +1407,14 @@ void parse_time_stamp_event(struct nvme_ocp_telemetry_event_descriptor *pevent_d
14041407
* @param pevent_fifos_object, event fifos json object pointer
14051408
* @param fp, input file pointer
14061409
*
1407-
* @return
1410+
* @return 0 success
14081411
*/
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);
1412+
int parse_pcie_event(
1413+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1414+
struct json_object *pevent_descriptor_obj,
1415+
__u8 *pevent_specific_data,
1416+
struct json_object *pevent_fifos_object,
1417+
FILE *fp);
14121418

14131419
/**
14141420
* @brief parses a nvme event fifo data to text or json formats
@@ -1419,11 +1425,14 @@ void parse_pcie_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descrip
14191425
* @param pevent_fifos_object, event fifos json object pointer
14201426
* @param fp, input file pointer
14211427
*
1422-
* @return
1428+
* @return 0 success
14231429
*/
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);
1430+
int parse_nvme_event(
1431+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1432+
struct json_object *pevent_descriptor_obj,
1433+
__u8 *pevent_specific_data,
1434+
struct json_object *pevent_fifos_object,
1435+
FILE *fp);
14271436

14281437
/**
14291438
* @brief parses common event fifo data to text or json formats
@@ -1449,9 +1458,12 @@ void parse_common_event(struct nvme_ocp_telemetry_event_descriptor *pevent_descr
14491458
* @param pevent_fifos_object, event fifos json object pointer
14501459
* @param fp, input file pointer
14511460
*
1452-
* @return
1461+
* @return 0 success
14531462
*/
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);
1463+
int parse_media_wear_event(
1464+
struct nvme_ocp_telemetry_event_descriptor *pevent_descriptor,
1465+
struct json_object *pevent_descriptor_obj,
1466+
__u8 *pevent_specific_data,
1467+
struct json_object *pevent_fifos_object,
1468+
FILE *fp);
14571469
#endif /* OCP_TELEMETRY_DECODE_H */

0 commit comments

Comments
 (0)