]> granicus.if.org Git - curl/commitdiff
urlapi: avoid index underflow for short ipv6 hostnames
authorPaul Dreik <github@pauldreik.se>
Fri, 20 Sep 2019 11:25:20 +0000 (13:25 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 21 Sep 2019 13:57:17 +0000 (15:57 +0200)
If the input hostname is "[", hlen will underflow to max of size_t when
it is subtracted with 2.

hostname[hlen] will then cause a warning by ubsanitizer:

runtime error: addition of unsigned offset to 0x<snip> overflowed to
0x<snip>

I think that in practice, the generated code will work, and the output
of hostname[hlen] will be the first character "[".

This can be demonstrated by the following program (tested in both clang
and gcc, with -O3)

int main() {
  char* hostname=strdup("[");
  size_t hlen = strlen(hostname);

  hlen-=2;
  hostname++;
  printf("character is %d\n",+hostname[hlen]);
  free(hostname-1);
}

I found this through fuzzing, and even if it seems harmless, the proper
thing is to return early with an error.

Closes #4389

lib/urlapi.c

index 903fe1804e2b5e1e7225a2e6613bee7a4b88c20f..1334236b2710bfa33c4debff6f1548249b3e22f5 100644 (file)
@@ -598,6 +598,8 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
   if(hostname[0] == '[') {
     char dest[16]; /* fits a binary IPv6 address */
     const char *l = "0123456789abcdefABCDEF:.";
+    if(hlen < 5) /* '[::1]' is the shortest possible valid string */
+      return CURLUE_MALFORMED_INPUT;
     hostname++;
     hlen -= 2;