Bug#609527: /lib/libc.so.6: Parallel gethostbyname2_r() fails if DNS server answers the first query when receiving the second.

2011-01-10 Thread Eirik Byrkjeflot Anonsen
Package: libc6
Version: 2.11.2-6
Severity: normal
File: /lib/libc.so.6


gethostbyname2_r() will sometimes fail if it is used to look up the
same host name concurrently in two threads.  I have tested a few
variations, and if the dns server behaves in one of the following
ways, gethostbyname2_r() will work correctly:

- answers both requests immediately. 
- answers both requests in order, but delays each (so both requests are 
received before the first response is sent) 
- answers both requests in reverse order 
- answers only the second request (of course, the first request will fail) 
- answers only the first request but delays it, so it is sent after receiving 
the second request (of course the second request will fail)

Whereas the following behaviour of the dns server will cause
gethostbyname2_r() to fail:

- waits for the second request, then answers the first immediately and drops 
everything else.

I have verified (using wireshark) that the packets sent on the network
are as expected according to my descriptions above.

I have test code to demonstrate the issue, and I'll add it to the bug
report as soon as I get permission to do so (this may take some time).

-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.32-5-amd64 (SMP w/8 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libc6 depends on:
ii  libc-bin  2.11.2-6   Embedded GNU C Library: Binaries
ii  libgcc1   1:4.4.4-15 GCC support library

libc6 recommends no packages.

Versions of packages libc6 suggests:
ii  debconf [debconf-2.0] 1.5.35 Debian configuration management sy
pn  glibc-doc none (no description available)
ii  locales   2.11.2-6   Embedded GNU C Library: National L

-- debconf information:
  glibc/upgrade: true
  glibc/restart-services:
  glibc/disable-screensaver:
  glibc/restart-failed:



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org



Bug#609527: /lib/libc.so.6: Parallel gethostbyname2_r() fails if DNS server answers the first query when receiving the second.

2011-01-10 Thread Eirik Byrkjeflot Anonsen
Here is the test code.

There are two programs, gethostbyname_threads.cpp and dnsserver.cpp.
Suggested compile command is in a comment at the top of each file.

Set up dnsserver as your DNS server (e.g. starting it as root and
modifying /etc/resolv.conf to use 127.0.0.1), and then run:

   gethostbyname_threads washingtonpost.com

(The dns server is extremely simpleminded and only knows to provide a
canned response to a very specific question.)

gethostbyname_threads will start two threads and look up the same
hostname in both threads.  It will then print out the result and exit.

The way the ifdefs in dnsserver.cpp is set up, it will wait for the
second request, immediately send a response to the first request and
then it will never send another packet.

Thus, I would expect the first gethostbyname2_r() call (in
gethostbyname_threads) to succeed and the second call to time out,
giving this output:

$ ./gethostbyname_threads washingtonpost.com
got: washingtonpost.com, IPv4: 12.129.147.65
gethostbyname2_r errored


Instead, both calls times out, and I get this output instead:

$ ./gethostbyname_threads washingtonpost.com
gethostbyname2_r errored
gethostbyname2_r errored

eirik


/*
g++ -o gethostbyname_threads gethostbyname_threads.cpp -lpthread

Permission to share code granted in Opera bug DSK-325405
 */

#include stdio.h
#include errno.h
#include netdb.h
#include pthread.h
#include sys/socket.h

void lookup(const char * hostname, int type);
void* lookup_both(void * hostname);

int main(int argc, const char ** argv)
{
if (argc != 2)
{
printf(usage: gethostbyname_threads hostname\n);
return 1;
}

const char * hostname = argv[1];

pthread_t t1;
pthread_t t2;
pthread_create(t1, 0, lookup_both, (void*)hostname);
pthread_create(t2, 0, lookup_both, (void*)hostname);
void * r;
pthread_join(t1, r);
pthread_join(t2, r);
return 0;
};

void * lookup_both(void * hostname)
{
lookup((char*)hostname, AF_INET);
return 0;
};


void print_hostent(struct hostent * res);

void lookup(const char * hostname, int type)
{
int error = 0;
struct hostent hostent;
struct hostent *res = 0;
const int BUFFER_SIZE=512;
char buffer[BUFFER_SIZE];
int err = gethostbyname2_r(hostname, type, hostent,
   buffer, BUFFER_SIZE,
   res, error);
if (err == ENOMEM || err == ENOBUFS)
printf(gethostbyname2_r OOMed\n);
else if (res)
print_hostent(res);
else
printf(gethostbyname2_r errored\n);
};


void print_hostent(struct hostent * res)
{
const char * type = UNKNOWN;
char addr[100];
addr[0] = 0;
if (res-h_addrtype == AF_INET)
{
type = IPv4;
unsigned char * a = (unsigned char*)res-h_addr_list[0];
if (a != 0)
snprintf(addr, 100, %d.%d.%d.%d, a[0], a[1], a[2], a[3]);
}
else if (res-h_addrtype == AF_INET6)
{
type = IPv6;
unsigned char * a = (unsigned char*)res-h_addr_list[0];
if (a != 0)
{
int next = 0;
for (int i = 0; i  res-h_length  next  90; i++)
{
if (i != 0  (i1) == 0)
{
addr[next] = ':';
next ++;
};
int len = snprintf(addr + next, 100 - next, %02x, a[i]);
next += len;
};
};
};
printf(got: %s, %s: %s\n, res-h_name, type, addr);
};
/*
g++ -o dnsserver dnsserver.cpp

Permission to share code granted in Opera bug DSK-325405
 */

#include sys/types.h
#include errno.h
#include netinet/in.h
#include stdio.h
#include string.h
#include sys/socket.h
#include unistd.h

int run_dns_server();
int main(int argc, const char ** argv)
{
return run_dns_server();
};


void handle_request(int sock, unsigned char * buf, size_t buflen, const struct sockaddr_in * addr);
void read_and_handle_single_request(int sock);
int run_dns_server()
{
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock  0)
{
fprintf(stderr, Failed to create socket (errno: %s)\n, strerror(errno));
return 1;
};

struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(53);
saddr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr*)saddr, sizeof(saddr)) != 0)
{
close(sock);
fprintf(stderr, Failed to bind socket (errno: %s)\n, strerror(errno));
return 1;
};

while (true)
{
read_and_handle_single_request(sock);
};
};

void read_and_handle_single_request(int sock)
{
const size_t bufsize = 1024;
unsigned char actual_buf[bufsize];
unsigned char * buf = actual_buf;

struct sockaddr_in remoteaddr;
socklen_t addrbuflen = sizeof(remoteaddr);
ssize_t got = recvfrom(sock, buf, bufsize, MSG_TRUNC, (struct sockaddr*)remoteaddr, addrbuflen);
if (got  0)
{
fprintf(stderr, Failed 

Bug#421854: xcb lock assertion with opera

2007-06-20 Thread Eirik Byrkjeflot Anonsen
Julien Cristau [EMAIL PROTECTED] writes:

 For what it's worth, using the current libx11-6 package from
 experimental and opera_9.21-20070510.6-shared-qt_en_i386.deb from
 www.opera.com, I'm unable to reproduce the crash.  Could the assertion
 failure be related to the known java bug with xcb [0], rather than a
 problem in opera itself?

It's certainly a possible explanation.

 I also get these messages when starting opera:
 ERROR: ld.so: object 'libjvm.so' from LD_PRELOAD cannot be preloaded: ignored.
 ERROR: ld.so: object 'libawt.so' from LD_PRELOAD cannot be preloaded: ignored.


These are most likely not important.  It's an old workaround for java
crashing due to having libraries loaded in the wrong order (libXt
before libXm).  Things have changed in various ways since we did
that...  (I think the crash problem is still there in principle, but
it doesn't seem to be widespread.)

eirik


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]



Bug#421854: xcb lock assertion with opera

2007-06-04 Thread Eirik Byrkjeflot Anonsen
I was sure I'd read somewhere on the xorg list that the xcb lock
assertions were invariably triggered by bugs in xlib.  I guess I
should know better than to trust my memory for such things :)

While opera does access xlib directly (I believe through plain xlib,
xft and xrender), I'd be very surprised if we do any explicit locking.
And indeed grep -r '[Ll]ockDisplay' turns up no relevant matches in
the opera source tree.  So I'd think the most likely culprit would be
qt.

eirik


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]