PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/package/ipmitool/0013-fru-sdr-Fix-id_string-buffer-overflows.patch

https://gitlab.com/cronmod-dev/buildroot
Patch | 141 lines | 119 code | 22 blank | 0 comment | 0 complexity | b3329175e4a57c4dff75988ffb8b026f MD5 | raw file
  1. From bf3ded3a474d85da99eb717acdcd8ff4f89f9879 Mon Sep 17 00:00:00 2001
  2. From: Chrostoper Ertl <chertl@microsoft.com>
  3. Date: Thu, 28 Nov 2019 17:13:45 +0000
  4. Subject: [PATCH] fru, sdr: Fix id_string buffer overflows
  5. Final part of the fixes for CVE-2020-5208, see
  6. https://github.com/ipmitool/ipmitool/security/advisories/GHSA-g659-9qxw-p7cp
  7. 9 variants of stack buffer overflow when parsing `id_string` field of
  8. SDR records returned from `CMD_GET_SDR` command.
  9. SDR record structs have an `id_code` field, and an `id_string` `char`
  10. array.
  11. The length of `id_string` is calculated as `(id_code & 0x1f) + 1`,
  12. which can be larger than expected 16 characters (if `id_code = 0xff`,
  13. then length will be `(0xff & 0x1f) + 1 = 32`).
  14. In numerous places, this can cause stack buffer overflow when copying
  15. into fixed buffer of size `17` bytes from this calculated length.
  16. [Retrieve from:
  17. https://github.com/ipmitool/ipmitool/commit/7ccea283dd62a05a320c1921e3d8d71a87772637]
  18. Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
  19. ---
  20. lib/ipmi_fru.c | 2 +-
  21. lib/ipmi_sdr.c | 40 ++++++++++++++++++++++++----------------
  22. 2 files changed, 25 insertions(+), 17 deletions(-)
  23. diff --git a/lib/ipmi_fru.c b/lib/ipmi_fru.c
  24. index af99aa9..98bc984 100644
  25. --- a/lib/ipmi_fru.c
  26. +++ b/lib/ipmi_fru.c
  27. @@ -3062,7 +3062,7 @@ ipmi_fru_print(struct ipmi_intf * intf, struct sdr_record_fru_locator * fru)
  28. return 0;
  29. memset(desc, 0, sizeof(desc));
  30. - memcpy(desc, fru->id_string, fru->id_code & 0x01f);
  31. + memcpy(desc, fru->id_string, __min(fru->id_code & 0x01f, sizeof(desc)));
  32. desc[fru->id_code & 0x01f] = 0;
  33. printf("FRU Device Description : %s (ID %d)\n", desc, fru->device_id);
  34. diff --git a/lib/ipmi_sdr.c b/lib/ipmi_sdr.c
  35. index 2a9cbe3..62aac08 100644
  36. --- a/lib/ipmi_sdr.c
  37. +++ b/lib/ipmi_sdr.c
  38. @@ -2084,7 +2084,7 @@ ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf,
  39. return -1;
  40. memset(desc, 0, sizeof (desc));
  41. - snprintf(desc, (sensor->id_code & 0x1f) + 1, "%s", sensor->id_string);
  42. + snprintf(desc, sizeof(desc), "%.*s", (sensor->id_code & 0x1f) + 1, sensor->id_string);
  43. if (verbose) {
  44. printf("Sensor ID : %s (0x%x)\n",
  45. @@ -2135,7 +2135,7 @@ ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf *intf,
  46. return -1;
  47. memset(desc, 0, sizeof (desc));
  48. - snprintf(desc, (mc->id_code & 0x1f) + 1, "%s", mc->id_string);
  49. + snprintf(desc, sizeof(desc), "%.*s", (mc->id_code & 0x1f) + 1, mc->id_string);
  50. if (verbose == 0) {
  51. if (csv_output)
  52. @@ -2228,7 +2228,7 @@ ipmi_sdr_print_sensor_generic_locator(struct ipmi_intf *intf,
  53. char desc[17];
  54. memset(desc, 0, sizeof (desc));
  55. - snprintf(desc, (dev->id_code & 0x1f) + 1, "%s", dev->id_string);
  56. + snprintf(desc, sizeof(desc), "%.*s", (dev->id_code & 0x1f) + 1, dev->id_string);
  57. if (!verbose) {
  58. if (csv_output)
  59. @@ -2285,7 +2285,7 @@ ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf *intf,
  60. char desc[17];
  61. memset(desc, 0, sizeof (desc));
  62. - snprintf(desc, (fru->id_code & 0x1f) + 1, "%s", fru->id_string);
  63. + snprintf(desc, sizeof(desc), "%.*s", (fru->id_code & 0x1f) + 1, fru->id_string);
  64. if (!verbose) {
  65. if (csv_output)
  66. @@ -2489,35 +2489,43 @@ ipmi_sdr_print_name_from_rawentry(struct ipmi_intf *intf, uint16_t id,
  67. int rc =0;
  68. char desc[17];
  69. + const char *id_string;
  70. + uint8_t id_code;
  71. memset(desc, ' ', sizeof (desc));
  72. switch ( type) {
  73. case SDR_RECORD_TYPE_FULL_SENSOR:
  74. record.full = (struct sdr_record_full_sensor *) raw;
  75. - snprintf(desc, (record.full->id_code & 0x1f) +1, "%s",
  76. - (const char *)record.full->id_string);
  77. + id_code = record.full->id_code;
  78. + id_string = record.full->id_string;
  79. break;
  80. +
  81. case SDR_RECORD_TYPE_COMPACT_SENSOR:
  82. record.compact = (struct sdr_record_compact_sensor *) raw ;
  83. - snprintf(desc, (record.compact->id_code & 0x1f) +1, "%s",
  84. - (const char *)record.compact->id_string);
  85. + id_code = record.compact->id_code;
  86. + id_string = record.compact->id_string;
  87. break;
  88. +
  89. case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
  90. record.eventonly = (struct sdr_record_eventonly_sensor *) raw ;
  91. - snprintf(desc, (record.eventonly->id_code & 0x1f) +1, "%s",
  92. - (const char *)record.eventonly->id_string);
  93. - break;
  94. + id_code = record.eventonly->id_code;
  95. + id_string = record.eventonly->id_string;
  96. + break;
  97. +
  98. case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
  99. record.mcloc = (struct sdr_record_mc_locator *) raw ;
  100. - snprintf(desc, (record.mcloc->id_code & 0x1f) +1, "%s",
  101. - (const char *)record.mcloc->id_string);
  102. + id_code = record.mcloc->id_code;
  103. + id_string = record.mcloc->id_string;
  104. break;
  105. +
  106. default:
  107. rc = -1;
  108. - break;
  109. - }
  110. + }
  111. + if (!rc) {
  112. + snprintf(desc, sizeof(desc), "%.*s", (id_code & 0x1f) + 1, id_string);
  113. + }
  114. - lprintf(LOG_INFO, "ID: 0x%04x , NAME: %-16s", id, desc);
  115. + lprintf(LOG_INFO, "ID: 0x%04x , NAME: %-16s", id, desc);
  116. return rc;
  117. }
  118. --
  119. 2.20.1