Strengthening input boundary validation and preventing memory disclosure

This commit is contained in:
Armel FAUVEAU committed 2026-08-24 19:41:20 +02:00
1 parent 265f83a447
commit ce6bf08b23
4 files changed
+26 -15

No files matched your search

+9 -7
View File
@@ -88,13 +88,14 @@ DECLARE_AIRCOPY_BANK(1)
// For settings only
static const AIRCOPY_Segment_t AIRCOPY_Segments_Settings[] = {
{ 0xA000, 0xA170, AIRCOPY_WRITE_BYTES },
{ 0x880E, 0x886E, AIRCOPY_WRITE_BYTES },
{ 0x9000, 0x90E5, AIRCOPY_WRITE_BYTES }, // VFO area (full 14 VFOs 0x9000..0x90E0) +
// Fox Hunt settings tail 0x90E0..0x90E5
// Ends are rounded to full Aircopy blocks. The extra bytes are unmapped
// EEPROM-compat holes (0x90E0..0x90E6 is the complete Fox Hunt tail).
{ 0xA000, 0xA180, AIRCOPY_WRITE_BYTES },
{ 0x880E, 0x888E, AIRCOPY_WRITE_BYTES },
{ 0x9000, 0x9100, AIRCOPY_WRITE_BYTES },
};
// total_blocks = ceil(0x170/64) + ceil(0x60/64) + ceil(0xE5/64) = 6 + 2 + 4 = 12
// total_blocks = 0x180/64 + 0x80/64 + 0x100/64 = 6 + 2 + 4 = 12
static const AIRCOPY_TransferMap_t AIRCOPY_Map_Settings = {
.segments = AIRCOPY_Segments_Settings,
.num_segments = 3,
@@ -154,7 +155,8 @@ static inline const AIRCOPY_Segment_t *AIRCOPY_FindSegmentForOffset(uint16_t off
{
const AIRCOPY_Segment_t *seg = &map->segments[i];
if (off >= seg->start_offset && off < seg->end_offset)
if (off >= seg->start_offset && off < seg->end_offset &&
((off - seg->start_offset) & (AIRCOPY_BLOCK_SIZE - 1u)) == 0u)
return seg;
}
@@ -426,4 +428,4 @@ void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gRequestDisplayScreen = DISPLAY_AIRCOPY;
}
#endif
#endif
+1 -3
View File
@@ -174,7 +174,6 @@ static void BEAM_SavePayloadToFirstFreeChannel(const BEAM_Payload_t *payload)
VFO_Info_t vfo;
RADIO_InitInfo(&vfo, channel, payload->rx_frequency);
// CRC + magic + version already validate the payload — no need to clamp fields.
vfo.TX_OFFSET_FREQUENCY = payload->tx_offset_frequency;
vfo.freq_config_RX.Code = payload->rx_code;
vfo.freq_config_TX.Code = payload->tx_code;
@@ -191,10 +190,9 @@ static void BEAM_SavePayloadToFirstFreeChannel(const BEAM_Payload_t *payload)
#ifdef ENABLE_DTMF_CALLING
vfo.DTMF_DECODING_ENABLE = payload->dtmf_decoding_enable;
#endif
vfo.STEP_SETTING = payload->step_setting;
vfo.STEP_SETTING = payload->step_setting < STEP_N_ELEM ? payload->step_setting : STEP_12_5kHz;
vfo.StepFrequency = gStepFrequencyTable[vfo.STEP_SETTING];
vfo.SCRAMBLING_TYPE = payload->scrambling_type;
vfo.Band = payload->band;
vfo.SCANLIST_PARTICIPATION = payload->scanlist;
vfo.Compander = payload->compander;
+12 -3
View File
@@ -298,9 +298,10 @@ static void SendVersion(uint32_t Port)
{
REPLY_0514_t Reply;
Reply.Data.Padding[0] = Reply.Data.Padding[1] = 0;
Reply.Header.ID = 0x0515;
Reply.Header.Size = sizeof(Reply.Data);
strcpy(Reply.Data.Version, Version);
strncpy(Reply.Data.Version, Version, sizeof(Reply.Data.Version));
Reply.Data.bHasCustomAesKey = bHasCustomAesKey;
Reply.Data.bIsInLockScreen = bIsInLockScreen;
Reply.Data.Challenge[0] = gChallenge[0];
@@ -434,6 +435,9 @@ static void CMD_051D(uint32_t Port, const uint8_t *pBuffer)
uint32_t Timestamp = 0;
if ((pCmd->Size & 7u) || pCmd->Header.Size < 8u + pCmd->Size)
return;
if(0) {}
#if defined(ENABLE_UART)
else if (Port == UART_PORT_UART)
@@ -560,6 +564,7 @@ static void CMD_052D(uint32_t Port, const uint8_t *pBuffer)
gIsLocked = bIsLocked;
Reply.Data.bIsLocked = bIsLocked;
Reply.Data.Padding[0] = Reply.Data.Padding[1] = Reply.Data.Padding[2] = 0;
SendReply(Port, &Reply, sizeof(Reply));
}
@@ -796,7 +801,9 @@ bool UART_IsCommandAvailable(uint32_t Port)
Crc = pUART_Command->Buffer[Size] | (pUART_Command->Buffer[Size + 1] << 8);
return CRC_Calculate(pUART_Command->Buffer, Size) == Crc;
return Size >= sizeof(Header_t) &&
pUART_Command->Header.Size <= Size - sizeof(Header_t) &&
CRC_Calculate(pUART_Command->Buffer, Size) == Crc;
}
#ifdef ENABLE_FEAT_F4HWN_MULTIBOOT
@@ -936,6 +943,8 @@ void UART_HandleCommand(uint32_t Port)
case 0x0724: // slot write: program bytes at slot+offset (slot pre-erased)
{
if (pUART_Command->Header.Size < 12u)
break;
gSerialConfigCountDown_500ms = 12; // keep serial mode alive (6 s)
uint8_t slot = pUART_Command->Data[0];
uint32_t offset = (uint32_t)pUART_Command->Data[2]
@@ -951,7 +960,7 @@ void UART_HandleCommand(uint32_t Port)
uint8_t status;
if (ts != mb_port_timestamp(Port))
status = MB_ERR_AUTH;
else if (len > 240u) // 12-byte prefix + data must fit Data[252]
else if (len > pUART_Command->Header.Size - 12u)
status = MB_ERR_SIZE;
else
status = MB_SlotWrite(slot, offset, &pUART_Command->Data[12], len);
+4 -2
View File
@@ -255,15 +255,17 @@ void UI_DisplayWelcome(void)
}
#endif
else {
char WelcomeString0[16];
char WelcomeString1[16];
char WelcomeString0[17];
char WelcomeString1[17];
char WelcomeString2[16];
char WelcomeString3[32];
// 0x0EB0
PY25Q16_ReadBuffer(0x00A0C8, WelcomeString0, 16);
WelcomeString0[16] = '\0';
// 0x0EC0
PY25Q16_ReadBuffer(0x00A0D8, WelcomeString1, 16);
WelcomeString1[16] = '\0';
sprintf(WelcomeString2, "%u.%02uV %u%%",
gBatteryVoltageAverage / 100,