From ac83334ff95831aa182431fb899087753878f327 Mon Sep 17 00:00:00 2001 From: Fredrik Orderud Date: Mon, 14 Oct 2024 10:45:37 +0200 Subject: [PATCH 1/4] Fix broken HIDPowerDevice_::sendDate method The method currently uses a local "bval" variable as argument when calling HID().SendReport(...). This is problematic, since the SendReport method doesn't use "bval" immediately. It instead captures a pointer to "bval" which is accessed when the report is sent at a later point. This leads to a use-after-free situation when the pointer captured by SendReport may no longer point to "bval". Propose to fix the issue by introducing a new "iManufacturerDate" member in the HIDPowerDevice class to act as persistent storage for the date value. --- src/HIDPowerDevice.cpp | 4 ++-- src/HIDPowerDevice.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/HIDPowerDevice.cpp b/src/HIDPowerDevice.cpp index 5217e04..045a64e 100755 --- a/src/HIDPowerDevice.cpp +++ b/src/HIDPowerDevice.cpp @@ -250,8 +250,8 @@ void HIDPowerDevice_::end(void) { } int HIDPowerDevice_::sendDate(uint16_t id, uint16_t year, uint8_t month, uint8_t day) { - uint16_t bval = (year - 1980)*512 + month * 32 + day; - return HID().SendReport(id, &bval, sizeof (bval)); + iManufacturerDate = (year - 1980)*512 + month * 32 + day; // from 4.2.6 Battery Settings in "Universal Serial Bus Usage Tables for HID Power Devices" + return HID().SendReport(id, &iManufacturerDate, sizeof(iManufacturerDate)); } int HIDPowerDevice_::sendReport(uint16_t id, const void* bval, int len) { diff --git a/src/HIDPowerDevice.h b/src/HIDPowerDevice.h index 888b860..366d7b7 100755 --- a/src/HIDPowerDevice.h +++ b/src/HIDPowerDevice.h @@ -128,6 +128,8 @@ class HIDPowerDevice_ { int setStringFeature(uint8_t id, const uint8_t* index, const char* data); +private: + uint16_t iManufacturerDate = 0; }; extern HIDPowerDevice_ PowerDevice; From 770ecec9637d4b99b4ed0078dbde3c87fbf358c8 Mon Sep 17 00:00:00 2001 From: Fredrik Orderud Date: Mon, 14 Oct 2024 10:48:51 +0200 Subject: [PATCH 2/4] Change HIDPowerDevice_::sendDate to send the date as a FEATURE report instead of a INPUT report, so that it matches the ManufacturerDate parameter in the HID descriptor. This is also required in order for the date to be picked up on Windows. --- src/HIDPowerDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HIDPowerDevice.cpp b/src/HIDPowerDevice.cpp index 045a64e..51bbbe1 100755 --- a/src/HIDPowerDevice.cpp +++ b/src/HIDPowerDevice.cpp @@ -251,7 +251,7 @@ void HIDPowerDevice_::end(void) { int HIDPowerDevice_::sendDate(uint16_t id, uint16_t year, uint8_t month, uint8_t day) { iManufacturerDate = (year - 1980)*512 + month * 32 + day; // from 4.2.6 Battery Settings in "Universal Serial Bus Usage Tables for HID Power Devices" - return HID().SendReport(id, &iManufacturerDate, sizeof(iManufacturerDate)); + return HID().SetFeature(id, &iManufacturerDate, sizeof(iManufacturerDate)); } int HIDPowerDevice_::sendReport(uint16_t id, const void* bval, int len) { From d91f51df48690090ef09efbe5c3db65c4f5ea40b Mon Sep 17 00:00:00 2001 From: Fredrik Orderud Date: Mon, 14 Oct 2024 10:39:19 +0200 Subject: [PATCH 3/4] Switch to using HIDPowerDevice_::sendDate method now that the method have been fixed. --- examples/UPS/UPS.ino | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/UPS/UPS.ino b/examples/UPS/UPS.ino index e908b1b..026dd2c 100644 --- a/examples/UPS/UPS.ino +++ b/examples/UPS/UPS.ino @@ -31,7 +31,6 @@ uint16_t iAvgTimeToEmpty = 7200; uint16_t iRemainTimeLimit = 600; int16_t iDelayBe4Reboot = -1; int16_t iDelayBe4ShutDown = -1; -uint16_t iManufacturerDate = 0; // initialized in setup function byte iAudibleAlarmCtrl = 2; // 1 - Disabled, 2 - Enabled, 3 - Muted @@ -92,9 +91,7 @@ void setup() { PowerDevice.setFeature(HID_PD_CPCTYGRANULARITY1, &bCapacityGranularity1, sizeof(bCapacityGranularity1)); PowerDevice.setFeature(HID_PD_CPCTYGRANULARITY2, &bCapacityGranularity2, sizeof(bCapacityGranularity2)); - uint16_t year = 2024, month = 10, day = 12; - iManufacturerDate = (year - 1980)*512 + month*32 + day; // from 4.2.6 Battery Settings in "Universal Serial Bus Usage Tables for HID Power Devices" - PowerDevice.setFeature(HID_PD_MANUFACTUREDATE, &iManufacturerDate, sizeof(iManufacturerDate)); + PowerDevice.sendDate(HID_PD_MANUFACTUREDATE, 2024, 10, 12); } void loop() { From 8bbade602abd908ae49c79a0652db249c18174b7 Mon Sep 17 00:00:00 2001 From: Fredrik Orderud Date: Tue, 15 Oct 2024 11:37:20 +0200 Subject: [PATCH 4/4] Change sendDate method to "int sendManufacturerDate(uint16_t year, uint8_t month, uint8_t day)" since it's anyhow tied to the ManufacturerDate parameter. --- examples/UPS/UPS.ino | 2 +- src/HIDPowerDevice.cpp | 4 ++-- src/HIDPowerDevice.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/UPS/UPS.ino b/examples/UPS/UPS.ino index 026dd2c..f951f85 100644 --- a/examples/UPS/UPS.ino +++ b/examples/UPS/UPS.ino @@ -91,7 +91,7 @@ void setup() { PowerDevice.setFeature(HID_PD_CPCTYGRANULARITY1, &bCapacityGranularity1, sizeof(bCapacityGranularity1)); PowerDevice.setFeature(HID_PD_CPCTYGRANULARITY2, &bCapacityGranularity2, sizeof(bCapacityGranularity2)); - PowerDevice.sendDate(HID_PD_MANUFACTUREDATE, 2024, 10, 12); + PowerDevice.sendManufacturerDate(2024, 10, 12); } void loop() { diff --git a/src/HIDPowerDevice.cpp b/src/HIDPowerDevice.cpp index 51bbbe1..884d278 100755 --- a/src/HIDPowerDevice.cpp +++ b/src/HIDPowerDevice.cpp @@ -249,9 +249,9 @@ void HIDPowerDevice_::setSerial(const char* s) { void HIDPowerDevice_::end(void) { } -int HIDPowerDevice_::sendDate(uint16_t id, uint16_t year, uint8_t month, uint8_t day) { +int HIDPowerDevice_::sendManufacturerDate(uint16_t year, uint8_t month, uint8_t day) { iManufacturerDate = (year - 1980)*512 + month * 32 + day; // from 4.2.6 Battery Settings in "Universal Serial Bus Usage Tables for HID Power Devices" - return HID().SetFeature(id, &iManufacturerDate, sizeof(iManufacturerDate)); + return HID().SetFeature(HID_PD_MANUFACTUREDATE, &iManufacturerDate, sizeof(iManufacturerDate)); } int HIDPowerDevice_::sendReport(uint16_t id, const void* bval, int len) { diff --git a/src/HIDPowerDevice.h b/src/HIDPowerDevice.h index 366d7b7..4a2710a 100755 --- a/src/HIDPowerDevice.h +++ b/src/HIDPowerDevice.h @@ -121,7 +121,7 @@ class HIDPowerDevice_ { void end(void); - int sendDate(uint16_t id, uint16_t year, uint8_t month, uint8_t day); + int sendManufacturerDate(uint16_t year, uint8_t month, uint8_t day); int sendReport(uint16_t id, const void* bval, int len); int setFeature(uint16_t id, const void* data, int len);