espressif / esp-lwip

Fork of lwIP (https://savannah.nongnu.org/projects/lwip/) with ESP-IDF specific patches
Other
79 stars 126 forks source link

Core panic when attempting to lookup bad domain in dns_gethostbyname (IDFGH-4508) #26

Closed scubachristopher closed 3 years ago

scubachristopher commented 3 years ago

Hi,

Providing a bad domain name creates a core panic on ESP32. Here is an arduino sketch that demonstrates the issue:

  //
  // Demonstrate DNS failure when a bad domain is provided
  //
  #include <WiFi.h>
  #include "lwip/dns.h"

  #define DOMAIN  "www.gggggoogle.com"

  const char* ssid     = "Christopher";
  const char* password = "XXXXXXXXX";
  ip_addr_t ipAddress;
  bool found;

  void dnsCallback(const char *name, const ip_addr_t *ip, void *arg)
  {
      ipAddress = *ip;
      found = true;
  }

  void setup()
  {
      ip_addr_t dnsserver;

      Serial.begin(115200);
      delay(100);

      Serial.printf("Connecting to %s\n", ssid);
      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.printf(".");
      }

      IP_ADDR4(&dnsserver, 8, 8, 8, 8);
      dns_setserver(0, &dnsserver);
      ipAddress = dns_getserver(0);
      Serial.printf("\nDNS server: %i.%i.%i.%i\n", ip4_addr1(&ipAddress.u_addr.ip4), ip4_addr2(&ipAddress.u_addr.ip4), 
        ip4_addr3(&ipAddress.u_addr.ip4), ip4_addr4(&ipAddress.u_addr.ip4));
  }

  void loop()
  {
    unsigned long timeout;
    err_t err;

    found = false;
    IP_ADDR4(&ipAddress, 0, 0, 0, 0);
    Serial.printf("Getting IP for URL: %s\n", DOMAIN);
    err = dns_gethostbyname(DOMAIN, &ipAddress, dnsCallback, NULL);
    Serial.printf("dns_gethostbyname returned %s\n", err == ERR_INPROGRESS ? "in progress" : err == ERR_OK ? "ok" : "dunno");
    timeout = millis() + 30000;
    while (!found && (timeout > millis())) {
      Serial.printf("Waiting with %5ld ms left\n", timeout - millis());
      delay(1000);
    }

    if (found) {
      Serial.printf("\nDNS returned: %i.%i.%i.%i\n", ip4_addr1(&ipAddress.u_addr.ip4), ip4_addr2(&ipAddress.u_addr.ip4), 
        ip4_addr3(&ipAddress.u_addr.ip4), ip4_addr4(&ipAddress.u_addr.ip4));
    }
    delay(5000);
  }

OUTPUT:

  14:45:52.062 -> rst:0x1 (POWERON_RESET),boot:0x13 (SConnecting to Christopher
  14:45:52.956 -> .
  14:45:52.956 -> DNS server: 8.8.8.8
  14:45:52.956 -> Getting IP for URL: www.gggggoogle.com
  14:45:52.956 -> dns_gethostbyname returned in progress
  14:45:52.956 -> Waiting with 30000 ms left
  14:45:53.025 -> Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
  14:45:53.025 -> Core 0 register dump:
  14:45:53.025 -> PC      : 0x4000c2e0  PS      : 0x00060c30  A0      : 0x800d0e70  A1      : 0x3ffb3cf0  
  14:45:53.061 -> A2      : 0x3ffc1010  A3      : 0x00000000  A4      : 0x00000014  A5      : 0x3ffc1010  
  14:45:53.061 -> A6      : 0x00060820  A7      : 0x00000001  A8      : 0x00000000  A9      : 0x3ffb3cc0  
  14:45:53.061 -> A10     : 0x3ffafda4  A11     : 0x00000007  A12     : 0x3ffbf890  A13     : 0x00000000  
  14:45:53.061 -> A14     : 0x3ffc1f30  A15     : 0x00000000  SAR     : 0x00000019  EXCCAUSE: 0x0000001c  
  14:45:53.061 -> EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  
  14:45:53.098 -> 
  14:45:53.098 -> Backtrace: 0x4000c2e0:0x3ffb3cf0 0x400d0e6d:0x3ffb3d00 0x401147ba:0x3ffb3d20 0x40115745:0x3ffb3d40 0x401198f5:0x3ffb3d90 0x4011e8fd:0x3ffb3dd0 0x40123b9a:0x3ffb3df0 0x4010ed7f:0x3ffb3e10 0x40088b7d:0x3ffb3e40
  14:45:53.098 -> 
  14:45:53.098 -> Rebooting...
  14:45:53.098 -> ets Jun  8 2016 00:22:57
  14:45:53.098 -> 
  14:45:53.098 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
  14:45:53.098 -> configsip: 0, SPIWP:0xee
  14:45:53.098 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
  14:45:53.134 -> mode:DIO, clock div:1
  14:45:53.134 -> load:0x3fff0018,len:4
  14:45:53.134 -> load:0x3fff001c,len:1216
  14:45:53.134 -> ho 0 tail 12 room 4
  14:45:53.134 -> load:0x40078000,len:9720
  14:45:53.134 -> ho 0 tail 12 room 4
  14:45:53.134 -> load:0x40080400,len:6352
  14:45:53.134 -> entry 0x400806b8
  14:45:53.467 -> Connecting to Christopher
  14:45:54.049 -> ..
  14:45:54.555 -> DNS server: 8.8.8.8
  14:45:54.555 -> Getting IP for URL: www.gggggoogle.com
  14:45:54.555 -> dns_gethostbyname returned in progress
  14:45:54.592 -> Waiting with 30000 ms left
  14:45:55.565 -> Waiting with 28999 ms left
  14:45:56.583 -> Waiting with 27999 ms left
  14:45:57.573 -> Waiting with 26999 ms left
  14:45:58.575 -> Waiting with 25999 ms left
  14:45:59.580 -> Waiting with 24999 ms left
  14:46:00.559 -> Waiting with 23999 ms left
  14:46:01.458 -> Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
  14:46:01.495 -> Core 0 register dump:
  14:46:01.495 -> PC      : 0x4000c2e0  PS      : 0x00060430  A0      : 0x800d0e70  A1      : 0x3ffb3d00  
  14:46:01.495 -> A2      : 0x3ffc1010  A3      : 0x00000000  A4      : 0x00000014  A5      : 0x3ffc1010  
  14:46:01.495 -> A6      : 0x00060823  A7      : 0x00000001  A8      : 0x00000000  A9      : 0x3ffb3dd0  
  14:46:01.495 -> A10     : 0x00000000  A11     : 0x4011457c  A12     : 0x3f40c084  A13     : 0x00001f66  
  14:46:01.495 -> A14     : 0x3ffcb73a  A15     : 0x000000c0  SAR     : 0x00000018  EXCCAUSE: 0x0000001c  
  14:46:01.530 -> EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  
  14:46:01.530 -> 
  14:46:01.530 -> Backtrace: 0x4000c2e0:0x3ffb3d00 0x400d0e6d:0x3ffb3d10 0x401147ba:0x3ffb3d30 0x40114df8:0x3ffb3d50 0x40114e93:0x3ffb3d70 0x4011581b:0x3ffb3d90 0x40114582:0x3ffb3db0 0x40114405:0x3ffb3dd0 0x401145c0:0x3ffb3df0 0x4010ed1c:0x3ffb3e10 0x40088b7d:0x3ffb3e40
  14:46:01.563 -> 
  14:46:01.563 -> Rebooting...

I've never seen the delay loop iterate more than 7 seconds, but I see panic's after 1, 2 seconds. It never returns anything other than ERR_INPROGRESS.

Thanks for looking into this!

igrr commented 3 years ago

@scubachristopher it looks like LwIP is invoking the callback with ip_addr_t *ip == NULL, and you are dereferencing the NULL pointer in dnsCallback. According to LwIP API reference, this argument is a "pointer to an ip_addr_t containing the IP address of the hostname, or NULL if the name could not be found (or on any other error)".

scubachristopher commented 3 years ago

Ahh -- makes sense. Thanks