From beb14deba56dbbda1e1b93ba07514c6ffc120d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 23 Aug 2026 14:46:02 +0200 Subject: [PATCH] httpd: send_counter(): Validate phys_port_idx and better error handling --- httpd/httpd.c | 9 +-------- httpd/page_impl.c | 30 ++++++++++++++++++++++-------- httpd/page_impl.h | 4 +++- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/httpd/httpd.c b/httpd/httpd.c index 8f52631..411ba0c 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -758,16 +758,9 @@ void httpd_appcall(void) parse_short(q + 15); send_vlan(short_parsed); } else if (is_word(q, "/counters.json")) { - /* The port is one raw character of the request line and - * indexes a nine entry table, so bound it here instead - * of trusting the client to have sent a digit. Anything - * below '0' wraps well past eight, so the one test - * covers both ends. */ uint8_t cport = q[20] - '0'; - if (cport > 8) + if (send_counters(cport)) send_bad_request(); - else - send_counters(cport); } else if (is_word(q, "/eee.json")) { send_eee(); } else if (is_word(q, "/bandwidth.json")) { diff --git a/httpd/page_impl.c b/httpd/page_impl.c index 92aeb1a..4bcf497 100644 --- a/httpd/page_impl.c +++ b/httpd/page_impl.c @@ -289,17 +289,25 @@ void send_vlan(uint16_t vlan) slen += strtox(outbuf + slen, "\"}"); } - -void send_counters(char port) +/* Send counters + * Only accepts physical port idx to 0-8. + * Returns an error if the port physical don't exists. + */ +bool send_counters(uint8_t phys_port_idx) { - dbg_string("send_counters called: "); dbg_byte(port); dbg_char('\n'); + if (phys_port_idx > 8) + goto err; + uint8_t log_port = machine.phys_to_log_port[phys_port_idx]; + if (log_port == 0) + goto err; + + dbg_string("send_counters called: "); dbg_byte(phys_port_idx); dbg_char('\n'); slen = strtox(outbuf, HTTP_RESPONCE_JSON); - dbg_string("sending counters\n"); - dbg_byte(port); - uint8_t i = machine.phys_to_log_port[port]; - slen += strtox(outbuf + slen, "["); + dbg_string("sending counters\n"); dbg_byte(phys_port_idx); + + char_to_html('['); for (uint8_t counter = 0; counter < 0x37; counter++) { - STAT_GET(counter, i); + STAT_GET(counter, log_port); slen += strtox(outbuf + slen, "\"0x"); reg_to_html(RTL837X_STAT_V_HIGH); reg_to_html_long(RTL837X_STAT_V_LOW); @@ -308,6 +316,12 @@ void send_counters(char port) char_to_html(','); } char_to_html(']'); + + return false; + +err: + dbg_string("Error: counters: phy_port_idx don't exists\n"); + return true; } diff --git a/httpd/page_impl.h b/httpd/page_impl.h index 7907285..1cbd94e 100644 --- a/httpd/page_impl.h +++ b/httpd/page_impl.h @@ -1,7 +1,9 @@ #ifndef __PAGE_IMPL_H__ #define __PAGE_IMPL_H__ -void send_counters(char port); +#include + +bool send_counters(uint8_t phys_port_idx); void send_status(void); void send_vlan(uint16_t vlan); void send_basic_info(void);