Harden legacy bounds
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
6f18b65217
commit
e2a7635f2f
3 changed files with 228 additions and 49 deletions
|
|
@ -5,6 +5,7 @@
|
|||
#include <cstring>
|
||||
|
||||
#include "../../switch_pro_descriptors.h"
|
||||
#include "../../switch_pro_bounds.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
@ -88,6 +89,73 @@ bool legacy_string_descriptors_match_exact_bytes() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool legacy_output_classifier_rejects_invalid_report_framing() {
|
||||
const uint8_t report[] = {0x01, 0x00};
|
||||
CHECK(switch_pro_classify_output_report(nullptr, 2) == SwitchProOutputReportKind::Ignore);
|
||||
CHECK(switch_pro_classify_output_report(report, 0) == SwitchProOutputReportKind::Ignore);
|
||||
CHECK(switch_pro_classify_output_report(report, 1) == SwitchProOutputReportKind::Ignore);
|
||||
CHECK(switch_pro_classify_output_report(report, 65) == SwitchProOutputReportKind::Ignore);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool legacy_feature_reports_reject_short_payloads_and_accept_bounds() {
|
||||
const uint8_t report[] = {0x01, 0x00};
|
||||
CHECK(switch_pro_classify_output_report(report, 15) == SwitchProOutputReportKind::Ignore);
|
||||
CHECK(switch_pro_classify_output_report(report, 16) == SwitchProOutputReportKind::Feature);
|
||||
CHECK(switch_pro_classify_output_report(report, 64) == SwitchProOutputReportKind::Feature);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool legacy_configuration_and_rumble_reports_reject_short_payloads() {
|
||||
const uint8_t configuration[] = {0x80, 0x00};
|
||||
const uint8_t rumble[] = {0x10, 0x00};
|
||||
const uint8_t noop[] = {0x00, 0x00};
|
||||
CHECK(switch_pro_classify_output_report(configuration, 1) == SwitchProOutputReportKind::Ignore);
|
||||
CHECK(switch_pro_classify_output_report(configuration, 2) == SwitchProOutputReportKind::Configuration);
|
||||
CHECK(switch_pro_classify_output_report(rumble, 9) == SwitchProOutputReportKind::Ignore);
|
||||
CHECK(switch_pro_classify_output_report(rumble, 10) == SwitchProOutputReportKind::Rumble);
|
||||
CHECK(switch_pro_classify_output_report(noop, 2) == SwitchProOutputReportKind::Noop);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool legacy_spi_read_rejects_payload_overflow_at_forty_five_bytes() {
|
||||
CHECK(switch_pro_spi_read_size_fits(0));
|
||||
CHECK(switch_pro_spi_read_size_fits(44));
|
||||
CHECK(!switch_pro_spi_read_size_fits(45));
|
||||
CHECK(!switch_pro_spi_read_size_fits(255));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool legacy_flash_read_copies_in_range_data_through_exact_end() {
|
||||
const uint8_t source[] = {1, 2, 3, 4};
|
||||
uint8_t destination[] = {0xAA, 0xAA, 0xAA, 0xAA};
|
||||
CHECK(switch_pro_fill_flash_read(destination, 4, source, 4, 0, 4) == 4);
|
||||
CHECK(destination[0] == 1 && destination[3] == 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool legacy_flash_read_prefills_partial_source_end_with_ff() {
|
||||
const uint8_t source[] = {1, 2};
|
||||
uint8_t destination[] = {0xAA, 0xAA, 0xAA, 0xAA};
|
||||
CHECK(switch_pro_fill_flash_read(destination, 4, source, 2, 0, 4) == 4);
|
||||
CHECK(destination[0] == 1 && destination[1] == 2);
|
||||
CHECK(destination[2] == 0xFF && destination[3] == 0xFF);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool legacy_flash_read_leaves_canaries_on_invalid_range_or_null_source() {
|
||||
const uint8_t source[] = {1, 2};
|
||||
uint8_t destination[] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
|
||||
CHECK(switch_pro_fill_flash_read(destination + 1, 4, source, 2, 3, 4) == 4);
|
||||
CHECK(destination[0] == 0xAA && destination[5] == 0xAA);
|
||||
CHECK(destination[1] == 0xFF && destination[4] == 0xFF);
|
||||
CHECK(switch_pro_fill_flash_read(destination + 1, 4, nullptr, 2, 0, 4) == 4);
|
||||
CHECK(destination[0] == 0xAA && destination[5] == 0xAA);
|
||||
CHECK(destination[1] == 0xFF && destination[4] == 0xFF);
|
||||
CHECK(switch_pro_fill_flash_read(nullptr, 4, source, 2, 0, 4) == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void run_legacy_descriptor_tests(TestRunner& runner) {
|
||||
|
|
@ -95,4 +163,11 @@ void run_legacy_descriptor_tests(TestRunner& runner) {
|
|||
runner.run("legacy configuration descriptor exact bytes", legacy_configuration_descriptor_matches_exact_bytes);
|
||||
runner.run("legacy HID report descriptor exact bytes", legacy_hid_report_descriptor_matches_exact_bytes);
|
||||
runner.run("legacy string descriptors exact bytes", legacy_string_descriptors_match_exact_bytes);
|
||||
runner.run("legacy output classifier rejects invalid report framing", legacy_output_classifier_rejects_invalid_report_framing);
|
||||
runner.run("legacy feature reports reject short payloads and accept bounds", legacy_feature_reports_reject_short_payloads_and_accept_bounds);
|
||||
runner.run("legacy configuration and rumble reports reject short payloads", legacy_configuration_and_rumble_reports_reject_short_payloads);
|
||||
runner.run("legacy SPI read rejects payload overflow at 45 bytes", legacy_spi_read_rejects_payload_overflow_at_forty_five_bytes);
|
||||
runner.run("legacy flash read copies in-range data through exact end", legacy_flash_read_copies_in_range_data_through_exact_end);
|
||||
runner.run("legacy flash read prefills partial source end with FF", legacy_flash_read_prefills_partial_source_end_with_ff);
|
||||
runner.run("legacy flash read leaves canaries on invalid range or null source", legacy_flash_read_leaves_canaries_on_invalid_range_or_null_source);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue