View Issue Details

IDProjectCategoryView StatusLast Update
0002479GNUnetGNSpublic2012-11-05 18:34
ReporterLRN Assigned Toschanzen  
PriorityhighSeveritycrashReproducibilityalways
Status closedResolutionfixed 
PlatformW32OSNTOS Version6.1.7601
Product VersionGit master 
Target Version0.9.4Fixed in Version0.9.4 
Summary0002479: Crash in GNS service while resolving a name
Descriptionr22468+6
Steps To ReproduceTried purging the namestore - didn't help.
This is the current code for gns helper that does the actual lookup.
If you want short version, here it is:
GNUNET_GNS_lookup_zone (gns, "www.gnunet", zone, GNUNET_GNS_RECORD_A,
      GNUNET_YES, shorten_key, &process_ip_lookup_result, rq);
where "zone" and "shorten_key" are retrieved in the same way gnunet-gns does it.

The long version:
static void
get_ip_from_hostname (struct GNUNET_SERVER_Client *client,
    const wchar_t *name, int af, GUID sc)
{
  struct request *rq;
  char *hostname;
  size_t strl;
  size_t namelen;
  uint32_t rtype;

  if (name)
    namelen = wcslen (name);
  else
    namelen = 0;
  if (namelen > 0)
    hostname = (char *) u16_to_u8 (name, namelen + 1, NULL, &strl);
  
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "W32 DNS resolver asked to look up %s for `%s'.\n",
              af == AF_INET ? "IPv4" : af == AF_INET6 ? "IPv6" : "anything",
              hostname);
  rq = GNUNET_malloc (sizeof (struct request));
  rq->sc = sc;
  rq->client = client;
  rq->af = af;
  if (rq->af != AF_INET && rq->af != AF_INET6)
    rq->af = AF_INET;
  if (namelen)
  {
    rq->name = GNUNET_malloc ((namelen + 1) * sizeof (wchar_t));
    memcpy (rq->name, name, (namelen + 1) * sizeof (wchar_t));
    rq->u8name = hostname;
  }

  if (IsEqualGUID (&SVCID_DNS_TYPE_A, &sc))
    rtype = GNUNET_GNS_RECORD_A;
  else if (IsEqualGUID (&SVCID_DNS_TYPE_NS, &sc))
    rtype = GNUNET_GNS_RECORD_NS;
  else if (IsEqualGUID (&SVCID_DNS_TYPE_CNAME, &sc))
    rtype = GNUNET_GNS_RECORD_CNAME;
  else if (IsEqualGUID (&SVCID_DNS_TYPE_SOA, &sc))
    rtype = GNUNET_GNS_RECORD_SOA;
  else if (IsEqualGUID (&SVCID_DNS_TYPE_PTR, &sc))
    rtype = GNUNET_GNS_RECORD_PTR;
  else if (IsEqualGUID (&SVCID_DNS_TYPE_MX, &sc))
    rtype = GNUNET_GNS_RECORD_MX;
  else if (IsEqualGUID (&SVCID_DNS_TYPE_TEXT, &sc))
    rtype = GNUNET_GNS_RECORD_TXT;
  else if (IsEqualGUID (&SVCID_DNS_TYPE_AAAA, &sc))
    rtype = GNUNET_GNS_RECORD_AAAA;
  else if (IsEqualGUID (&SVCID_DNS_TYPE_SRV, &sc))
    rtype = GNUNET_GNS_RECORD_SRV;
  else if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, &sc))
    rtype = GNUNET_GNS_RECORD_A;
  if (NULL != GNUNET_GNS_lookup_zone (gns, hostname, zone, rtype,
      GNUNET_YES, shorten_key, &process_ip_lookup_result, rq))
  {
    GNUNET_SERVER_client_keep (client);
  }
  else
  {
    if (namelen)
    {
      GNUNET_free (rq->name);
      free (rq->u8name);
    }
    GNUNET_free (rq);
  }
}


static void
handle_get (void *cls, struct GNUNET_SERVER_Client *client,
            const struct GNUNET_MessageHeader *message)
{
  uint16_t msize;
  const struct GNUNET_W32RESOLVER_GetMessage *msg;
  GUID sc;
  uint16_t size;
  uint64_t data4;
  int i;
  const wchar_t *hostname;
  int af;

  msize = ntohs (message->size);
  if (msize < sizeof (struct GNUNET_W32RESOLVER_GetMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  msg = (const struct GNUNET_W32RESOLVER_GetMessage *) message;
  size = msize - sizeof (struct GNUNET_W32RESOLVER_GetMessage);
  af = ntohl (msg->af);
  sc.Data1 = ntohl (msg->sc_data1);
  sc.Data2 = ntohs (msg->sc_data2);
  sc.Data3 = ntohs (msg->sc_data3);
  data4 = GNUNET_ntohll (msg->sc_data4);
  for (i = 0; i < 8; i++)
    sc.Data4[i] = 0xFF & (data4 >> ((7 - i) * 8));
  
  hostname = (const wchar_t *) &msg[1];
  if (hostname[size - 1] != L'\0')
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  get_ip_from_hostname (client, hostname, af, sc);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
  return;
}

static void
run (void *cls, struct GNUNET_SERVER_Handle *server,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  static const struct GNUNET_SERVER_MessageHandler handlers[] = {
    {&handle_get, NULL, GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST, 0},
    {NULL, NULL, 0, 0}
  };

  char* keyfile;
  struct GNUNET_CRYPTO_RsaPrivateKey *key = NULL;
  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
  struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename;

  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
                                                           "ZONEKEY", &keyfile))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                "No private key for root zone found, using default!\n");
    zone = NULL;
  }
  else
  {
    if (GNUNET_YES == GNUNET_DISK_file_test (keyfile))
    {
      key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
      GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
      GNUNET_CRYPTO_short_hash(&pkey,
                         sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                         &user_zone);
      zone = &user_zone;
      GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename);
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Using zone: %s!\n", &zonename);
      GNUNET_CRYPTO_rsa_key_free(key);
    }
    GNUNET_free(keyfile);
  }

  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
                                                   "SHORTEN_ZONEKEY", &keyfile))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                "No shorten key found!\n");
    shorten_key = NULL;
  }
  else
  {
    if (GNUNET_YES == GNUNET_DISK_file_test (keyfile))
    {
      shorten_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
    }
    GNUNET_free(keyfile);
  }

  gns = GNUNET_GNS_connect (cfg);
  if (gns == NULL)
    return;

  GNUNET_SERVER_add_handlers (server, handlers);
}
Additional Information
Reading symbols from D:\Progs\GNUnet\bin\gnunet-service-gns.exe...done.
(gdb) thread 1
[Switching to thread 1 (Thread 16352.0x4780)]
#0  0x771af8b1 in ntdll!RtlUpdateClonedSRWLock () from C:\Windows\SysWOW64\ntdll.dll
(gdb) bt
#0  0x771af8b1 in ntdll!RtlUpdateClonedSRWLock () from C:\Windows\SysWOW64\ntdll.dll
#1  0x771af8b1 in ntdll!RtlUpdateClonedSRWLock () from C:\Windows\SysWOW64\ntdll.dll
#2  0x76770a91 in WaitForSingleObjectEx () from C:\Windows\syswow64\KernelBase.dll
#3  0x000002b0 in ?? ()
#4  0x00000000 in ?? ()
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
_gcry_sexp_find_token (list=0xdf00046, tok=<optimized out>, toklen=<optimized out>) at sexp.c:445
445               p += n;
(gdb) bt
#0  _gcry_sexp_find_token (list=0xdf00046, tok=<optimized out>, toklen=<optimized out>) at sexp.c:445
#1  0x62adaa44 in key_from_sexp (array=0x28f268, sexp=0xdf00046, topname=0x62b1197c "public-key", elems=0x62b11979 "ne") at crypto_rsa.c:129
#2  0x62adabe3 in GNUNET_CRYPTO_rsa_key_get_public (priv=0x20982e8, pub=0x28f2b0) at crypto_rsa.c:188
#3  0x00407a61 in start_shorten (atail=0x20c2190, key=0x20982e8) at gnunet-service-gns_resolver.c:705
#4  0x0040c153 in resolve_record_ns (rh=0x208f508) at gnunet-service-gns_resolver.c:2094
#5  0x004104ec in handle_delegation_ns (cls=0x20c2078, rh=0x208f508, rd_count=0, rd=0x0) at gnunet-service-gns_resolver.c:3226
#6  0x00410ba6 in process_delegation_result_ns (cls=0x208f508, key=0x0, expiration=..., name=0x0, rd_count=0, rd=0x0, signature=0x0)
    at gnunet-service-gns_resolver.c:3344
#7  0x67f816de in handle_lookup_name_response (qe=0x2093f50, msg=0x28f8b0, size=808) at namestore_api.c:319
#8  0x67f822ce in manage_record_operations (qe=0x2093f50, msg=0x28f8b0, type=432, size=808) at namestore_api.c:542
#9  0x67f830a3 in process_namestore_message (cls=0x2099ee0, msg=0x28f8b0) at namestore_api.c:725
#10 0x62ac3d9b in receive_task (cls=0x2095a88, tc=0x28fc70) at client.c:594
#11 0x62af7dcf in run_ready (rs=0x789ff0, ws=0x78b008) at scheduler.c:608
#12 0x62af8576 in GNUNET_SCHEDULER_run (task=0x62b0475e <service_task>, task_cls=0x28fe10) at scheduler.c:796
#13 0x62b0549a in GNUNET_SERVICE_run (argc=3, argv=0x208bd50, service_name=0x419794 "gns", options=GNUNET_SERVICE_OPTION_NONE, task=0x404f73 <run>,
    task_cls=0x0) at service.c:1788
#14 0x00405a47 in main (argc=3, argv=0x208bd50) at gnunet-service-gns.c:1431
(gdb) l
440                   d = newlist->d;
441                   memcpy ( d, head, n ); d += n;
442                   *d++ = ST_STOP;
443                   return normalize ( newlist );
444                 }
445               p += n;
446             }
447           else if ( *p == ST_DATA )
448             {
449               memcpy ( &n, ++p, sizeof n ); p += sizeof n;
(gdb) p p
$1 = (const byte *) 0xdf00046 <Address 0xdf00046 out of bounds>
(gdb) p n
$2 = <optimized out>
(gdb) up
#1  0x62adaa44 in key_from_sexp (array=0x28f268, sexp=0xdf00046, topname=0x62b1197c "public-key", elems=0x62b11979 "ne") at crypto_rsa.c:129
129       list = gcry_sexp_find_token (sexp, topname, 0);
(gdb) p sexp
$3 = (gcry_sexp_t) 0xdf00046
(gdb) up
#2  0x62adabe3 in GNUNET_CRYPTO_rsa_key_get_public (priv=0x20982e8, pub=0x28f2b0) at crypto_rsa.c:188
188       rc = key_from_sexp (skey, priv->sexp, "public-key", "ne");
(gdb) p *priv
$4 = {sexp = 0xdf00046}
(gdb) up
#3  0x00407a61 in start_shorten (atail=0x20c2190, key=0x20982e8) at gnunet-service-gns_resolver.c:705
705       GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
(gdb) p key
$5 = (struct GNUNET_CRYPTO_RsaPrivateKey *) 0x20982e8
(gdb) up
#4  0x0040c153 in resolve_record_ns (rh=0x208f508) at gnunet-service-gns_resolver.c:2094
2094        start_shorten (rh->authority_chain_tail,
(gdb) p rh->priv_key
$6 = (struct GNUNET_CRYPTO_RsaPrivateKey *) 0x20982e8
(gdb) p *rh
$7 = {next = 0x0, prev = 0x0, rd = {data = 0x0, expiration_time = 0, data_size = 0, record_type = 0, flags = GNUNET_NAMESTORE_RF_NONE}, rd_count = 0,
  name = "www", '\000' <repeats 249 times>, answered = 0, only_cached = 0, authority = {bits = {1945656268, 91006392, 1972010730, 3324250595, 1499202865,
      2816105319, 2284685793, 4036374849}}, authority_name = "www", '\000' <repeats 59 times>, get_handle = 0x0, timeout = {
    rel_value = 18446744073709551615}, vpn_handle = 0x0, dns_sock = 0x0, dns_name = '\000' <repeats 252 times>, dns_zone = '\000' <repeats 252 times>,
  dns_addr = {sin_family = 0, sin_port = 0, sin_addr = {S_un = {S_un_b = {s_b1 = 0 '\000', s_b2 = 0 '\000', s_b3 = 0 '\000', s_b4 = 0 '\000'}, S_un_w = {
          s_w1 = 0, s_w2 = 0}, S_addr = 0}}, sin_zero = "\000\000\000\000\000\000\000"}, dns_resolver_handle = 0x0, dns_read_task = 0,
  dns_raw_packet = 0x0, dns_raw_packet_size = 0, timeout_task = 0, timeout_cont = 0, timeout_cont_cls = 0x0, proc = 0x40e988 <handle_record_ns>,
  proc_cls = 0x20c2078, authority_chain_head = 0x20c2190, authority_chain_tail = 0x20c2190, status = 0, private_local_zone = {bits = {1945656268,
      91006392, 1972010730, 3324250595, 1499202865, 2816105319, 2284685793, 4036374849}}, priv_key = 0x20982e8, dht_heap_node = 0x0, id = 1,
  namestore_task = 0x0}
TagsNo tags attached.

Activities

There are no notes attached to this issue.

Issue History

Date Modified Username Field Change
2012-07-04 08:58 LRN New Issue
2012-07-04 08:58 LRN Status new => assigned
2012-07-04 08:58 LRN Assigned To => schanzen
2012-07-04 09:27 Christian Grothoff Target Version => 0.9.4
2012-07-04 09:29 Christian Grothoff Priority normal => high
2012-07-04 20:52 schanzen Status assigned => resolved
2012-07-04 20:52 schanzen Resolution open => fixed
2012-07-04 20:53 Christian Grothoff Fixed in Version => 0.9.4
2012-11-05 18:34 Christian Grothoff Status resolved => closed