From c04a5fc3a41660700e215fce59eaa5781c207917 Mon Sep 17 00:00:00 2001 From: DrDoof <8052722+DrDoof@users.noreply.github.com> Date: Sat, 12 Sep 2026 16:24:15 +0200 Subject: [PATCH 1/3] flash: bail out of a bulk read of zero length flash_read_bulk() ends its copy loop only through the comparisons len == 1|2|3|4, so a length of zero matches none of them. The following len -= 4 wraps on uint16_t to 65532 and reaches 4 only after 16384 iterations, writing 65536 bytes to the destination and overwriting the whole XDATA space. send_config() gets there with valid_len 0 whenever the stored configuration begins with a NUL byte, which is the state left by uploading an empty configuration file. Every later request for the configuration page then clears the management VLAN and the STP flag and replaces the host address, while the switch keeps running and keeps forwarding traffic. --- rtl837x_flash.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtl837x_flash.c b/rtl837x_flash.c index 5f04c88a..f18d21fb 100644 --- a/rtl837x_flash.c +++ b/rtl837x_flash.c @@ -222,6 +222,10 @@ void flash_read_jedecid(void) void flash_read_bulk(__xdata uint8_t *dst) { short status; + + if (!flash_region.len) + return; + flash_configure_sio(); while (flash_read_status() & STATUS_REG_BUSY_MASK); flash_configure_mmio(); From e0df37f359e6b2be8a7df8d9846f9cd03130511e Mon Sep 17 00:00:00 2001 From: DrDoof <8052722+DrDoof@users.noreply.github.com> Date: Sat, 12 Sep 2026 18:34:59 +0200 Subject: [PATCH 2/3] flash: bail out of a security-register read of zero length flash_read_security() ends its loop the same way flash_read_bulk() did before the previous commit: only through comparisons with 1, 2, 3 and 4. A length of zero matches none of them, the following subtraction wraps on uint16_t and the loop keeps printing until the counter comes back down to 4. No caller passes zero today, since the only one is the CLI with a constant length of 40, but the bound belongs in the function rather than in whoever calls it. --- rtl837x_flash.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtl837x_flash.c b/rtl837x_flash.c index f18d21fb..3805d730 100644 --- a/rtl837x_flash.c +++ b/rtl837x_flash.c @@ -262,6 +262,9 @@ void flash_read_bulk(__xdata uint8_t *dst) void flash_read_security(void) { + if (!flash_region.len) + return; + flash_configure_sio(); while (flash_read_status() & STATUS_REG_BUSY_MASK); From 3b3f36256c94c31125e31922eb064ed0ed1b95e5 Mon Sep 17 00:00:00 2001 From: d00f <8052722+DrDoof@users.noreply.github.com> Date: Tue, 15 Sep 2026 15:28:36 +0200 Subject: [PATCH 3/3] flash: drop the unused status variable from flash_read_bulk() Since #427 the busy wait calls flash_read_status() directly, so the local it used to go through is no longer read anywhere. --- rtl837x_flash.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/rtl837x_flash.c b/rtl837x_flash.c index 3805d730..2ec5bc3f 100644 --- a/rtl837x_flash.c +++ b/rtl837x_flash.c @@ -221,8 +221,6 @@ void flash_read_jedecid(void) */ void flash_read_bulk(__xdata uint8_t *dst) { - short status; - if (!flash_region.len) return;