mirror of
https://github.com/espressif/openthread.git
synced 2026-09-01 06:49:54 +00:00
[energy-scan-server] reject scan request with zero channel mask (#12137)
This commit validates that the Channel Mask TLVs in a TMF Energy Scan request are non-zero. Additionally, this commit clamps the Count TLV value to the valid range (1, 2, and 3) as required by the Thread specification. The `test_otci` is updated to use count 3 (previously 4). An Energy Scan request with a zero `Channel Mask` is invalid and can cause the device to start a scan that takes a long time or never completes. This change rejects such requests, preventing the device from getting stuck. This was discovered by fuzzer test.
This commit is contained in:
@@ -62,10 +62,13 @@ void EnergyScanServer::HandleTmf<kUriEnergyScan>(Coap::Message &aMessage, const
|
|||||||
VerifyOrExit(aMessage.IsPostRequest());
|
VerifyOrExit(aMessage.IsPostRequest());
|
||||||
|
|
||||||
SuccessOrExit(Tlv::Find<MeshCoP::CountTlv>(aMessage, count));
|
SuccessOrExit(Tlv::Find<MeshCoP::CountTlv>(aMessage, count));
|
||||||
|
count = Clamp(count, kMinCount, kMaxCount);
|
||||||
|
|
||||||
SuccessOrExit(Tlv::Find<MeshCoP::PeriodTlv>(aMessage, period));
|
SuccessOrExit(Tlv::Find<MeshCoP::PeriodTlv>(aMessage, period));
|
||||||
SuccessOrExit(Tlv::Find<MeshCoP::ScanDurationTlv>(aMessage, scanDuration));
|
SuccessOrExit(Tlv::Find<MeshCoP::ScanDurationTlv>(aMessage, scanDuration));
|
||||||
|
|
||||||
SuccessOrExit(MeshCoP::ChannelMaskTlv::FindIn(aMessage, mask));
|
SuccessOrExit(MeshCoP::ChannelMaskTlv::FindIn(aMessage, mask));
|
||||||
|
VerifyOrExit(mask != 0);
|
||||||
|
|
||||||
mReportMessage.Reset(Get<Tmf::Agent>().NewPriorityConfirmablePostMessage(kUriEnergyReport));
|
mReportMessage.Reset(Get<Tmf::Agent>().NewPriorityConfirmablePostMessage(kUriEnergyReport));
|
||||||
VerifyOrExit(mReportMessage != nullptr);
|
VerifyOrExit(mReportMessage != nullptr);
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
static constexpr uint32_t kScanDelay = 1000; // SCAN_DELAY (milliseconds)
|
static constexpr uint32_t kScanDelay = 1000; // SCAN_DELAY (milliseconds)
|
||||||
static constexpr uint32_t kReportDelay = 500; // Delay before sending a report (milliseconds)
|
static constexpr uint32_t kReportDelay = 500; // Delay before sending a report (milliseconds)
|
||||||
|
static constexpr uint8_t kMinCount = 1;
|
||||||
|
static constexpr uint8_t kMaxCount = 3;
|
||||||
|
|
||||||
template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||||
|
|
||||||
|
|||||||
@@ -754,10 +754,10 @@ class TestOTCI(unittest.TestCase):
|
|||||||
rtt: Dict[str, float] = cast(Dict[str, float], statistics['round_trip_time'])
|
rtt: Dict[str, float] = cast(Dict[str, float], statistics['round_trip_time'])
|
||||||
self.assertTrue(rtt['min'] - 1e-9 <= rtt['avg'] <= rtt['max'] + 1e-9)
|
self.assertTrue(rtt['min'] - 1e-9 <= rtt['avg'] <= rtt['max'] + 1e-9)
|
||||||
|
|
||||||
ed_report = commissioner.commissioner_energy_scan(3 << commissioner.get_channel(), 4, 32, 1000,
|
ed_report = commissioner.commissioner_energy_scan(3 << commissioner.get_channel(), 3, 32, 1000,
|
||||||
child1.get_ipaddr_rloc())
|
child1.get_ipaddr_rloc())
|
||||||
comm_chan = commissioner.get_channel()
|
comm_chan = commissioner.get_channel()
|
||||||
self.assertEqual({comm_chan: [-30, -30, -30, -30], comm_chan + 1: [-30, -30, -30, -30]}, ed_report)
|
self.assertEqual({comm_chan: [-30, -30, -30], comm_chan + 1: [-30, -30, -30]}, ed_report)
|
||||||
|
|
||||||
commissioner.commissioner_announce(TEST_CHANNEL_MASK, 1, 32, child1.get_ipaddr_rloc())
|
commissioner.commissioner_announce(TEST_CHANNEL_MASK, 1, 32, child1.get_ipaddr_rloc())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user