From e416da5416543319fc208328217d37881dd00a66 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 4610d5a..4c61315 100755 --- a/src/HIDPowerDevice.cpp +++ b/src/HIDPowerDevice.cpp @@ -251,8 +251,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 3b146b9..21395f9 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 9e37c67cc7ed8b8eea2ec1ce1f737a6ed9dc80d2 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 4c61315..ac43e16 100755 --- a/src/HIDPowerDevice.cpp +++ b/src/HIDPowerDevice.cpp @@ -252,7 +252,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 71c2682376e4d58e1fd502da7706befdab615bca 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 3961337..bd18624 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 fc7767985667cb7d7d8550ff0cd13990f7d12c99 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 bd18624..b26d80e 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 ac43e16..da7ad41 100755 --- a/src/HIDPowerDevice.cpp +++ b/src/HIDPowerDevice.cpp @@ -250,9 +250,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 21395f9..19ee67c 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);