Package: polipo Version: 0.9.9-1 Severity: important Tags: patch In atom.c around line 182, the va_list args can be used twice between va_start and va_end. This results in undefined behaviour according to the va_start manpage. At least on amd64, it results in a segmentation fault. I have attached a patch that contains a fix, and as a bonus another patch that removes a lot of compiler warnings.
-- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable') Architecture: amd64 (x86_64) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.17.7 Locale: LANG=nl_NL.UTF-8, LC_CTYPE=nl_NL.UTF-8 (charmap=UTF-8) Versions of packages polipo depends on: ii libc6 2.3.6.ds1-4 GNU C Library: Shared libraries polipo recommends no packages. -- no debconf information
--- polipo-0.9.9.orig/atom.c 2006-09-02 19:28:22.152075017 +0200 +++ polipo-0.9.9/atom.c 2006-09-02 20:45:20.079873542 +0200 @@ -182,16 +182,19 @@ va_start(args, format); n = vsnprintf(buf, 150, format, args); + va_end(args); + if(n >= 0 && n < 150) { atom = internAtomN(buf, n); } else { + va_start(args, format); s = vsprintf_a(format, args); if(s != NULL) { atom = internAtom(s); free(s); } + va_end(args); } - va_end(args); return atom; }
diff -urN polipo-0.9.9.orig/atom.c polipo-0.9.9/atom.c --- polipo-0.9.9.orig/atom.c 2006-09-02 19:28:22.152075017 +0200 +++ polipo-0.9.9/atom.c 2006-09-02 20:45:20.079873542 +0200 @@ -72,7 +72,7 @@ atomHashTable[h] = atom; used_atoms++; } - do_log(D_ATOM_REFCOUNT, "A 0x%x %d++\n", (unsigned)atom, atom->refcount); + do_log(D_ATOM_REFCOUNT, "A %p %d++\n", atom, atom->refcount); atom->refcount++; return atom; } @@ -132,7 +132,7 @@ if(atom == NULL) return NULL; - do_log(D_ATOM_REFCOUNT, "A 0x%x %d++\n", (unsigned)atom, atom->refcount); + do_log(D_ATOM_REFCOUNT, "A %p %d++\n", atom, atom->refcount); assert(atom->refcount >= 1 && atom->refcount < 50000); atom->refcount++; return atom; @@ -144,7 +144,7 @@ if(atom == NULL) return; - do_log(D_ATOM_REFCOUNT, "A 0x%x %d--\n", (unsigned)atom, atom->refcount); + do_log(D_ATOM_REFCOUNT, "A %p %d--\n", atom, atom->refcount); assert(atom->refcount >= 1 && atom->refcount < 50000); atom->refcount--; diff -urN polipo-0.9.9.orig/client.c polipo-0.9.9/client.c --- polipo-0.9.9.orig/client.c 2006-09-02 19:28:22.166072523 +0200 +++ polipo-0.9.9/client.c 2006-09-02 19:32:37.060315276 +0200 @@ -105,8 +105,8 @@ connection->fd = fd; connection->timeout = timeout; - do_log(D_CLIENT_CONN, "Accepted client connection 0x%x\n", - (unsigned)connection); + do_log(D_CLIENT_CONN, "Accepted client connection %p\n", + connection); connection->flags = CONN_READER; @@ -236,8 +236,8 @@ return; } - do_log(D_CLIENT_CONN, "Closing client connection 0x%x\n", - (unsigned)connection); + do_log(D_CLIENT_CONN, "Closing client connection %p\n", + connection); while(1) { HTTPRequestPtr requestee; @@ -1734,8 +1734,8 @@ connection->offset = request->from; httpSetTimeout(connection, 120); - do_log(D_CLIENT_DATA, "Serving on 0x%x for 0x%x: offset %d len %d\n", - (unsigned)connection, (unsigned)object, + do_log(D_CLIENT_DATA, "Serving on %p for %p: offset %d len %d\n", + connection, object, connection->offset, len); do_stream_h(IO_WRITE | (connection->te == TE_CHUNKED && len > 0 ? IO_CHUNKED : 0), @@ -1914,8 +1914,8 @@ if(len2 == 0) { httpSetTimeout(connection, 120); do_log(D_CLIENT_DATA, - "Serving on 0x%x for 0x%x: offset %d len %d\n", - (unsigned)connection, (unsigned)object, + "Serving on %p for %p: offset %d len %d\n", + connection, object, connection->offset, len); /* IO_NOTNOW in order to give other clients a chance to run. */ do_stream(IO_WRITE | IO_NOTNOW | @@ -1927,8 +1927,8 @@ } else { httpSetTimeout(connection, 120); do_log(D_CLIENT_DATA, - "Serving on 0x%x for 0x%x: offset %d len %d + %d\n", - (unsigned)connection, (unsigned)object, + "Serving on %p for %p: offset %d len %d + %d\n", + connection, object, connection->offset, len, len2); do_stream_2(IO_WRITE | IO_NOTNOW | (connection->te == TE_CHUNKED ? IO_CHUNKED : 0) | diff -urN polipo-0.9.9.orig/http.c polipo-0.9.9/http.c --- polipo-0.9.9.orig/http.c 2006-09-02 19:28:22.153074839 +0200 +++ polipo-0.9.9/http.c 2006-09-02 19:31:58.367452637 +0200 @@ -199,8 +199,8 @@ new = scheduleTimeEvent(secs, httpTimeoutHandler, sizeof(connection), &connection); if(!new) { - do_log(L_ERROR, "Couldn't schedule timeout for connection 0x%x\n", - (unsigned)connection); + do_log(L_ERROR, "Couldn't schedule timeout for connection %p\n", + connection); return -1; } } else { diff -urN polipo-0.9.9.orig/object.c polipo-0.9.9/object.c --- polipo-0.9.9.orig/object.c 2006-09-02 19:28:22.162073235 +0200 +++ polipo-0.9.9/object.c 2006-09-02 19:30:56.639145655 +0200 @@ -268,7 +268,7 @@ ObjectPtr retainObject(ObjectPtr object) { - do_log(D_REFCOUNT, "O 0x%x %d++\n", (unsigned)object, object->refcount); + do_log(D_REFCOUNT, "O %p %d++\n", object, object->refcount); object->refcount++; return object; } @@ -276,7 +276,7 @@ void releaseObject(ObjectPtr object) { - do_log(D_REFCOUNT, "O 0x%x %d--\n", (unsigned)object, object->refcount); + do_log(D_REFCOUNT, "O %p %d--\n", object, object->refcount); object->refcount--; if(object->refcount == 0) { assert(!object->handlers && !(object->flags & OBJECT_INPROGRESS)); @@ -288,7 +288,7 @@ void releaseNotifyObject(ObjectPtr object) { - do_log(D_REFCOUNT, "O 0x%x %d--\n", (unsigned)object, object->refcount); + do_log(D_REFCOUNT, "O %p %d--\n", object, object->refcount); object->refcount--; if(object->refcount > 0) { notifyObject(object); @@ -302,7 +302,7 @@ void lockChunk(ObjectPtr object, int i) { - do_log(D_LOCK, "Lock 0x%x[%d]: ", (unsigned)object, i); + do_log(D_LOCK, "Lock %p[%d]: ", object, i); assert(i >= 0); if(i >= object->numchunks) objectSetChunks(object, i + 1); @@ -313,7 +313,7 @@ void unlockChunk(ObjectPtr object, int i) { - do_log(D_LOCK, "Unlock 0x%x[%d]: ", (unsigned)object, i); + do_log(D_LOCK, "Unlock %p[%d]: ", object, i); assert(i >= 0 && i < object->numchunks); assert(object->chunks[i].locked > 0); object->chunks[i].locked--; @@ -467,8 +467,8 @@ { int rc; - do_log(D_OBJECT_DATA, "Adding data to 0x%x (%d) at %d: %d bytes\n", - (unsigned)object, object->length, offset, len); + do_log(D_OBJECT_DATA, "Adding data to %p (%d) at %d: %d bytes\n", + object, object->length, offset, len); if(len == 0) return 1;