98 lines
3.1 KiB
Diff
98 lines
3.1 KiB
Diff
From 4705fa040e114ed480d153c262bcb6f9963b6380 Mon Sep 17 00:00:00 2001
|
|
From: fengtao40 <fengtao40@huawei.com>
|
|
Date: Tue, 11 Feb 2020 21:13:33 -0500
|
|
Subject: [PATCH] Fix buffer overflow
|
|
|
|
---
|
|
include/ipmitool/ipmi_channel.h | 45 +++++++++++++++++++++++++++++++++
|
|
lib/ipmi_channel.c | 10 ++++++--
|
|
2 files changed, 53 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/include/ipmitool/ipmi_channel.h b/include/ipmitool/ipmi_channel.h
|
|
index 3ade2d5..1e9d097 100644
|
|
--- a/include/ipmitool/ipmi_channel.h
|
|
+++ b/include/ipmitool/ipmi_channel.h
|
|
@@ -81,6 +81,51 @@ struct channel_access_t {
|
|
uint8_t user_level_auth;
|
|
};
|
|
|
|
+/*
|
|
+ * The Cipher Suite Record Format from table 22-18 of the IPMI v2.0 spec
|
|
+ */
|
|
+enum cipher_suite_format_tag {
|
|
+ STANDARD_CIPHER_SUITE = 0xc0,
|
|
+ OEM_CIPHER_SUITE = 0xc1,
|
|
+};
|
|
+#ifdef HAVE_PRAGMA_PACK
|
|
+#pragma pack(1)
|
|
+#endif
|
|
+struct std_cipher_suite_record_t {
|
|
+ uint8_t start_of_record;
|
|
+ uint8_t cipher_suite_id;
|
|
+ uint8_t auth_alg;
|
|
+ uint8_t integrity_alg;
|
|
+ uint8_t crypt_alg;
|
|
+} ATTRIBUTE_PACKING;
|
|
+struct oem_cipher_suite_record_t {
|
|
+ uint8_t start_of_record;
|
|
+ uint8_t cipher_suite_id;
|
|
+ uint8_t iana[3];
|
|
+ uint8_t auth_alg;
|
|
+ uint8_t integrity_alg;
|
|
+ uint8_t crypt_alg;
|
|
+} ATTRIBUTE_PACKING;
|
|
+#ifdef HAVE_PRAGMA_PACK
|
|
+#pragma pack(0)
|
|
+#endif
|
|
+#define CIPHER_ALG_MASK 0x3f
|
|
+#define MAX_CIPHER_SUITE_RECORD_OFFSET 0x40
|
|
+#define MAX_CIPHER_SUITE_DATA_LEN 0x10
|
|
+#define LIST_ALGORITHMS_BY_CIPHER_SUITE 0x80
|
|
+
|
|
+/* Below is the theoretical maximum number of cipher suites that could be
|
|
+ * reported by a BMC. That is with the Get Channel Cipher Suites Command, at 16
|
|
+ * bytes at a time and 0x40 requests, it can report 1024 bytes, which is about
|
|
+ * 204 standard records or 128 OEM records. Really, we probably don't need more
|
|
+ * than about 20, which is the full set of standard records plus a few OEM
|
|
+ * records.
|
|
+ */
|
|
+#define MAX_CIPHER_SUITE_COUNT (MAX_CIPHER_SUITE_RECORD_OFFSET * \
|
|
+ MAX_CIPHER_SUITE_DATA_LEN / \
|
|
+ sizeof(struct std_cipher_suite_record_t))
|
|
+
|
|
+
|
|
/*
|
|
* The Get Authentication Capabilities response structure
|
|
* From table 22-15 of the IPMI v2.0 spec
|
|
diff --git a/lib/ipmi_channel.c b/lib/ipmi_channel.c
|
|
index e1fc75f..025ee74 100644
|
|
--- a/lib/ipmi_channel.c
|
|
+++ b/lib/ipmi_channel.c
|
|
@@ -378,7 +378,10 @@ ipmi_get_channel_cipher_suites(struct ipmi_intf *intf, const char *payload_type,
|
|
lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites");
|
|
return -1;
|
|
}
|
|
- if (rsp->ccode > 0) {
|
|
+ if (rsp->ccode
|
|
+ || rsp->data_len < 1
|
|
+ || rsp->data_len > sizeof(uint8_t) + MAX_CIPHER_SUITE_DATA_LEN)
|
|
+ {
|
|
lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s",
|
|
val2str(rsp->ccode, completion_code_vals));
|
|
return -1;
|
|
@@ -413,7 +416,10 @@ ipmi_get_channel_cipher_suites(struct ipmi_intf *intf, const char *payload_type,
|
|
lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites");
|
|
return -1;
|
|
}
|
|
- if (rsp->ccode > 0) {
|
|
+ if (rsp->ccode
|
|
+ || rsp->data_len < 1
|
|
+ || rsp->data_len > sizeof(uint8_t) + MAX_CIPHER_SUITE_DATA_LEN)
|
|
+ {
|
|
lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s",
|
|
val2str(rsp->ccode, completion_code_vals));
|
|
return -1;
|
|
--
|
|
2.19.1
|
|
|