From f82415f6b91a857a0668de39cab583d95f1dc501 Mon Sep 17 00:00:00 2001 From: Johny Mattsson Date: Wed, 28 Oct 2015 16:14:07 +1100 Subject: [PATCH] Fix to do TCP port number randomization at boot. This addresses the issue where a server would otherwise reject a valid connection attempt from a rebooted node, due to the server thinking that packet belonged to a recently closed session. By starting off the local TCP port numbers at random* points each boot the risk of port reuse across a reboot is significantly reduced. *) As random as can be had via the lower 12 bits of the ccounter. --- app/lwip/core/tcp.c | 2 +- app/user/user_main.c | 18 ++++++++++++++++++ ld/nodemcu.ld | 9 +++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/lwip/core/tcp.c b/app/lwip/core/tcp.c index 362b3961..b09a4f7f 100644 --- a/app/lwip/core/tcp.c +++ b/app/lwip/core/tcp.c @@ -635,7 +635,7 @@ tcp_new_port(void) #define TCP_LOCAL_PORT_RANGE_START 4096 #define TCP_LOCAL_PORT_RANGE_END 0x7fff #endif - static u16_t port = TCP_LOCAL_PORT_RANGE_START; + static u16_t port __attribute__((section(".port"))) = TCP_LOCAL_PORT_RANGE_START; again: if (++port >= TCP_LOCAL_PORT_RANGE_END) { diff --git a/app/user/user_main.c b/app/user/user_main.c index 8aacba27..ef6c63dc 100644 --- a/app/user/user_main.c +++ b/app/user/user_main.c @@ -51,6 +51,21 @@ void TEXT_SECTION_ATTR user_start_trampoline (void) } +/* To avoid accidentally losing the fix for the TCP port randomization + * during an LWIP upgrade, we've implemented most it outside the LWIP + * source itself. This enables us to test for the presence of the fix + * /at link time/ and error out if it's been lost. + * The fix itself consists of putting the function-static 'port' variable + * into its own section, and get the linker to provide an alias for it. + * From there we can then manually randomize it at boot. + */ +static inline void tcp_random_port_init (void) +{ + extern uint16_t _tcp_new_port_port; // provided by the linker script + _tcp_new_port_port += xthal_get_ccount () % 4096; +} + + void task_lua(os_event_t *e){ char* lua_argv[] = { (char *)"lua", (char *)"-i", NULL }; NODE_DBG("Task task_lua started.\n"); @@ -145,6 +160,9 @@ void nodemcu_init(void) // char* lua_argv[] = { (char *)"lua", (char *)"-e", (char *)"pwm.setup(0,100,50) pwm.start(0) pwm.stop(0)", NULL }; // lua_main( 3, lua_argv ); // NODE_DBG("Flash sec num: 0x%x\n", flash_get_sec_num()); + + tcp_random_port_init (); + task_init(); system_os_post(LUA_TASK_PRIO,SIG_LUA,'s'); } diff --git a/ld/nodemcu.ld b/ld/nodemcu.ld index a72c3405..d849bba1 100644 --- a/ld/nodemcu.ld +++ b/ld/nodemcu.ld @@ -113,6 +113,15 @@ SECTIONS { _data_start = ABSOLUTE(.); *(.data) + + /* Hook for randomizing TCP start numbers */ + _tcp_new_port_port = ABSOLUTE(.); + */liblwip.a:tcp.o(.port) + /* Verify that the LWIP source has been patched as needed, or fail with + * a divide by zero error (../ld/nodemcu.ld:xxx / by zero) */ + _tcp_new_port_port_size = ABSOLUTE(.) - _tcp_new_port_port; + _ensure_tcp_port_randomization_fix_presence = 1 / _tcp_new_port_port_size; + *(.data.*) *(.gnu.linkonce.d.*) *(.data1)