On 12/26/2011 04:45 AM, intrigeri wrote: > Hi fellow Tails developers, hi Jacob! > > > Context > ======= > > We've been under repeated pressure to replace Polipo with Privoxy in > Tails. Most of the time, such attempts were made without much > knowledge of the Tails context, and were backed with plain wrong > reasons. Recently, Jacob advised us to remove Polipo; I assume it's > for good reasons, that are still to be explained in details though. >
Tor in general is ditching Polipo; we've worked on some patches, I think almost none of them actually landed upstream. I did an audit with some other people and we decided that it was pretty difficult to harden it. Additionally, there was a huge bug that prevented large file download but I think by now it is fixed. > Let's see what good reasons we may have to switch to Privoxy; there > are some. Let's look, with a fresh eye, what are the pros and cons of > these two pieces of software, as far as Tails is concerned. > Sure. > Preliminary note: in Tails 0.10, only APT, wget and applications that > obey the HTTP_PROXY / http_proxy environment variables will use > Polipo. Iceweasel _won't_. > Ok. > > Polipo is not supported by anyone for anonymity reasons > ======================================================= > > Correct. > > Who does support Privoxy for anonymity reasons? > We're using it for all Tor stuff now when we need an HTTP proxy. > > Polipo does not support downloading big files > ============================================= > > With our current configuration, "big" means bigger than 64MB: > https://tails.boum.org/bugs/impossible_to_download_files_bigger_than_64M_with_Iceweasel/ > Huh, I guess it's still not fixed (!) in newer versions. > AFAIK, in Tails 0.10, only wget will be affected. This is an annoying > limitation for command-line users (especially when you learn about it > *after* having waited hours of stalled download), but not *that* > critical now that iceweasel is not affected by it anymore. > That's enough, I think. > Time to ship curl (that supports SOCKS5) instead of wget? It was > suggested to ship curl, plus a simplistic wrapper script called > "wget", that would pass curl the URL-looking arguments, and would > abort loudly, pointing at the curl documentation, if anything more > clever was attempted. > I think that would be a useful addition but I'm still a fan of wget. > > We already ship Polipo and know its possible weaknesses, > while we don't know Privoxy weaknesses yet > ======================================================== > > Our Polipo configuration was inherited from Incognito. In the times > when Polipo was shipped in the TBB, it's been under severe scrutiny > for anonymity / privacy leaks, and more generally for security > problems. A few issues were discovered; AFAIK all such issues are > either fixed in the polipo package (1.0.4.1-1.1) shipped in Debian > Squeeze, or don't affect Tails. This should be double-checked, though: > https://tails.boum.org/todo/applications_audit/polipo/ > I had a polipo branch that I gave to Chris long ago. It had a bunch of fixes and general improvement ideas. > Issues of the same kind may very well affect Privoxy too. If we were > to switch to it, we would have to gather existing research results on > this topic, check them, copy / design / adapt a configuration that > works around possible issues, etc.; we could probably start from > Liberté Linux's configuration, but this does not remove the need to > audit it in any way. Such work is non-trivial, and it's not obvious we > would gain anything at all, in the end, from a privacy or anonymity > point-of-view; even, the risk to make things worse exists. > I think an audit of Privoxy has a better return; we already know Polipo isn't great, it has bugs and is likely buggy in dangerous ways. We don't know that about Privoxy. > > Privoxy supports content filtering > ================================== > > Invalid for many reasons. Some of the most obvious ones are: > > - malicious content may be inserted as HTTPS to workaround filtering > of the HTTP streams > - if body filtering is enabled, Privoxy downloads every resource in > full before starting to deliver bytes to the client => much higher > latency experienced by the user; yeah, we don't care as we're not > really talking of web browsing; but then, what advantage would > body filtering provide to the APT and wget kind of usage, exactly? > I'd not use it anyway. > > Polipo has better latency / user-experience > =========================================== > > Invalid, as we're not thinking, TTBOMK, of inserting a HTTP proxy back > between Iceweasel and Polipo. > > > Privoxy allows one to designate different proxies for different URLs > ==================================================================== > > This would allow command-line applications in Tails to support > eepsites. My take on this is that it would be welcome, but not > compelling enough to make the balance weight much more on the side > of change. > > > Polipo is what's been used by most Tor users for years > ====================================================== > > TBB did ship Polipo, the Tor Debian / Ubuntu packages recommend Polipo > as the preferred alternative on top of Privoxy. Anonymity set++, etc., > we all know the deal. > We're not shipping either of them anymore, I just checked with helix. Privoxy is what we'd suggest if anything. > > Polipo is not very well maintained upstream > =========================================== > > This is not to be easily ignored. IIRC the upstream author abandoned > it for a while; it was more or less forked / maintained by the Tor > project in the meantime; the upstream author came back, but the > improvements made by Tor were not all merged yet. > Right. > OTOH, apart of the file size download limit, it's not as if we had had > to report many bugs against it. > There were a bunch. > > Polipo does caching > =================== > > We don't care, since we're not talking about web browsing anymore here. > We should care - leaving a copy of data around might complicate things. > > Jacob wants us to remove Polipo > =============================== > > Jacob, you talked of "lots of reliability/security issues" and told us > that "Privoxy is a better http proxy for most things". Would you > please elaborate, after reading this very email, _what_ exact issues > you're thinking of, and _what_ makes Privoxy that much better? > > % git branch * bugs master type-fixup I've attached the commits from bugs and type-fixup. They're old and I think Chris at least has seen all of the commits in these branches. All the best, Jacob > Wanna add more pros and cons? > > Cheers,
commit 7db83d6a303ff372a367afa68895fe1a19abb08f Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Fri Mar 19 19:34:36 2010 -0700 DNS issues diff --git a/dns.c b/dns.c index 1a5b39b..11957c4 100644 --- a/dns.c +++ b/dns.c @@ -1394,6 +1394,8 @@ stringToLabels(char *buf, int offset, int n, char *string) memcpy((_d), &(_dd), sizeof(unsigned)); } while(0); #endif + +/* This should be rewritten to use descriptive names for n, *d, m, etc... */ static int labelsToString(char *buf, int offset, int n, char *d, int m, int *j_return) { @@ -1413,6 +1415,7 @@ labelsToString(char *buf, int offset, int n, char *d, int m, int *j_return) if(i >= n) return -1; o = (ll & ~(3 << 6)) << 8 | *(unsigned char*)&buf[i]; i++; + /* XXX Is this possibly full of endless recursion? */ labelsToString(buf, o, n, &d[j], m - j, &k); j += k; break; @@ -1544,6 +1547,7 @@ dnsDecodeReply(char *buf, int offset, int n, int *id_return, error = EDNS_FORMAT; goto fail; } + /* This is missing check to see if i is still in buffer... */ DO_NTOHS(type, &buf[i]); i += 2; DO_NTOHS(class, &buf[i]); i += 2; @@ -1587,6 +1591,14 @@ do { \ for(j = 0; j < ancount; j++) { PARSE_ANSWER("an", fail); + /* XXX used length from network, instead of length from name-> ... + * also... + * For any request polipo makes for say yahoo.com, anything starting + * with y will match if the network returns a lie for the length... + * + * This is pretty sub-optimal... + * + */ if(strcasecmp_n(name->string, b, m) == 0) { if(class != 1) { do_log(D_DNS, "DNS: %s: unknown class %d.\n", commit 039e87e5bba790920101e6c39acab1246a1e49fc Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Fri Mar 19 19:06:58 2010 -0700 atomCat issues diff --git a/atom.c b/atom.c index ed18d92..68a5249 100644 --- a/atom.c +++ b/atom.c @@ -91,6 +91,10 @@ atomCat(AtomPtr atom, const char *string) char *s = buf; AtomPtr newAtom; int n = strlen(string); + /* XXX atom-length may be insanely large and overflow with n to be less + * than 128; n may also be a giant string - this is not safe. It's likely + * the case that we should ensure that atom-length is some MAX_SIZE that we + * never grow above... */ if(atom->length + n > 128) { s = malloc(atom->length + n + 1); if(s == NULL) commit 668d8e27a78adbf73194c5795562e1e565fc04c6 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Fri Mar 19 18:58:14 2010 -0700 Initial TODO notes diff --git a/TODO b/TODO new file mode 100644 index 0000000..e07f5ed --- /dev/null +++ b/TODO @@ -0,0 +1,35 @@ +We should enable as much exploit mitigation support as possible + + +The following relates to SOCKS4/SOCKS5 interfacing with Tor. + +Why does Polipo have DNS support at all? + Removal of all DNS code or force to be 127.0.01? + Removal! + Add --disable-dns flag? + Perhaps overload all functions to log, rather than resolve? + This will help us find stray calls that _would_ leak information + +Caching attacks + We need to have a new identity function for Polipo + We already have this in Vidalia and Tor - Polipo needs it too + Browser caching is possible bad news for privacy; is it worse with + Polipo? + + +Skipping nul bytes happens everywhere - this allows for lots of bad stuff. + Explicit length should be set (think pascal strings) + This leads to possible information leakage (but is better than + information leakage with certainty) + +A "metric shitload of" integer mismatches. + Likes we've got a lot of int overflows without reasonable or proper + (certainly unsafe) + +Polipo needs to have a minimal control interface + likely a unix socket to avoid XSRF and other browser injection attacks. + Tor solves this with a password or cookie, etc + Ironically, that password makes Tor nearly impossible to setup + +To prevent local timing/cache checking issues + a separate user per application, per user commit 24d58b9b2da6efd9936737facb95f6eeca35b3af Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Fri Mar 19 12:47:28 2010 -0700 debug this diff --git a/Makefile b/Makefile index e6fd085..33fae90 100644 --- a/Makefile +++ b/Makefile @@ -23,8 +23,8 @@ CDEBUGFLAGS = -Os -g -Wall # # _FORTIFY_SOURCE tells the C library to perform additional safety checks. # -# CDEBUGFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all \ -# -Wstack-protector -fwrapv + CDEBUGFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all \ + -Wstack-protector -fwrapv -ansi -Wextra # To prevent some kinds of exploitation at run time, fix up the program's # got table to be read only (also reorders structures) after the first program commit 3311a08029d70f26e1c074da474d17e5ffd51a92 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sun Dec 27 16:20:51 2009 +0100 linker hardening diff --git a/Makefile b/Makefile index 78c31ab..e6fd085 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,11 @@ CDEBUGFLAGS = -Os -g -Wall # CDEBUGFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all \ # -Wstack-protector -fwrapv +# To prevent some kinds of exploitation at run time, fix up the program's +# got table to be read only (also reorders structures) after the first program +# load. eg: ld -z relro -z now +LDFLAGS += -z relro -z now + # To compile on a pure POSIX system: # CC = c89 commit eca86763b2b6d643c51d289b602c76b6a8637a46 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 16:16:41 2009 +0200 int fixups diff --git a/chunk.h b/chunk.h index 78d9743..c916a30 100644 --- a/chunk.h +++ b/chunk.h @@ -39,7 +39,7 @@ THE SOFTWARE. #define CHUNKS(bytes) ((unsigned long)(bytes) / CHUNK_SIZE) extern int chunkLowMark, chunkHighMark, chunkCriticalMark; -extern int used_chunks; +extern unsigned long used_chunks; void preinitChunks(void); void initChunks(void); commit 682a25eaa5255192aeb641d84041d1fb965900bc Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 16:08:15 2009 +0200 Cleanup ints for chunk.c This makes a few variables into unsigned ints diff --git a/chunk.c b/chunk.c index a11cc3f..0daef1d 100644 --- a/chunk.c +++ b/chunk.c @@ -93,11 +93,12 @@ initChunksCommon() } -int used_chunks = 0; +unsigned long used_chunks = 0; static void maybe_free_chunks(int arenas, int force) { + /* CHUNKS returns (unsigned long) */ if(force || used_chunks >= CHUNKS(chunkHighMark)) { discardObjects(force, force); } @@ -291,7 +292,7 @@ typedef struct _ChunkArena { } ChunkArenaRec, *ChunkArenaPtr; static ChunkArenaPtr chunkArenas, currentArena; -static int numArenas; +static unsigned int numArenas; #define CHUNK_IN_ARENA(chunk, arena) \ ((arena)->chunks && \ (char*)(chunk) >= (arena)->chunks && \ @@ -304,7 +305,7 @@ static int numArenas; void initChunks(void) { - int i; + unsigned int i; used_chunks = 0; initChunksCommon(); pagesize = getpagesize(); @@ -333,7 +334,7 @@ static ChunkArenaPtr findArena() { ChunkArenaPtr arena = NULL; - int i; + unsigned int i; for(i = 0; i < numArenas; i++) { arena = &(chunkArenas[i]); @@ -436,7 +437,8 @@ void free_chunk_arenas() { ChunkArenaPtr arena; - int i, rc; + unsigned int i; + int rc; for(i = 0; i < numArenas; i++) { arena = &(chunkArenas[i]); @@ -457,7 +459,7 @@ int totalChunkArenaSize() { ChunkArenaPtr arena; - int i, size = 0; + unsigned int i, size = 0; for(i = 0; i < numArenas; i++) { arena = &(chunkArenas[i]); commit 249e31733b39b667cef16f22b3708f0aef9986c4 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 15:47:49 2009 +0200 Ensure we're dealing with ints during our compares We want to ensure that we're always using ints for comparisions with ints. diff --git a/io.c b/io.c index a64bc81..2cc7c08 100644 --- a/io.c +++ b/io.c @@ -458,7 +458,7 @@ do_connect(AtomPtr addr, int index, int port, assert(addr->length > 0 && addr->string[0] == DNS_A); assert(addr->length % sizeof(HostAddressRec) == 1); - if(index >= (addr->length - 1)/ sizeof(HostAddressRec)) + if(index >= (addr->length - 1)/ (int)sizeof(HostAddressRec)) index = 0; request.firstindex = index; @@ -521,7 +521,7 @@ do_scheduled_connect(int status, FdEventHandlerPtr event) assert(addr->length > 0 && addr->string[0] == DNS_A); assert(addr->length % sizeof(HostAddressRec) == 1); - assert(request->index < (addr->length - 1) / sizeof(HostAddressRec)); + assert(request->index < (addr->length - 1) / (int)sizeof(HostAddressRec)); if(status) { done = request->handler(status, event, request); commit 4613aa15cd94c687a7a58fb4200868a7ce9c7865 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 15:46:01 2009 +0200 Make AtomPtr's length element an int It was an unsigned short but it was largely used with ints. diff --git a/atom.h b/atom.h index 0b9adeb..ee0b8ec 100644 --- a/atom.h +++ b/atom.h @@ -23,7 +23,7 @@ THE SOFTWARE. typedef struct _Atom { unsigned int refcount; struct _Atom *next; - unsigned short length; + int length; char string[1]; } AtomRec, *AtomPtr; commit 6eb6e906565edaec5785709a9bb788fc8b7d4857 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 15:31:31 2009 +0200 Check the return value of fwrite() We weren't checking the return value of fwrite(). It was possible that our logging would fail and we would never know. diff --git a/config.c b/config.c index 60d9ec5..eb24419 100644 --- a/config.c +++ b/config.c @@ -102,6 +102,7 @@ declareConfigVariable(AtomPtr name, int type, void *value, static void printString(FILE *out, char *string, int html) { + int r = 0; if(html) { char buf[512]; int i; @@ -110,7 +111,10 @@ printString(FILE *out, char *string, int html) fprintf(out, "(overflow)"); return; } - fwrite(buf, 1, i, out); + r = fwrite(buf, 1, i, out); + if (r != i) { + printf("String printing failure: wrote %d, expected %d\n", r, i); + } } else { fprintf(out, "%s", string); } commit aaa5b04ca33c2dc16316ec734760fca25148c1a1 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 15:27:31 2009 +0200 Check the return value of fwrite() We weren't checking the return value of fwrite(). It was possible that our logging would fail and we would never know. diff --git a/log.c b/log.c index ec5c545..0f37771 100644 --- a/log.c +++ b/log.c @@ -470,9 +470,13 @@ really_do_log_error_v(int type, int e, const char *f, va_list args) void really_do_log_n(int type, const char *s, int n) { + int r = 0; if((type & LOGGING_MAX & logLevel) != 0) { if(logF) { - fwrite(s, n, 1, logF); + r = fwrite(s, n, 1, logF); + if (r != n) { + printf("Logging failure: wrote %d, expected %d\n", r, n); + } } #ifdef HAVE_SYSLOG if(logSyslog) commit 12f9f0d353322b6e0194722e5284666f8158e11a Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Thu Dec 10 22:17:07 2009 +0200 Add GCC-specific hardening flags to our Makefile. This adds support for fortified source, moves the integer wrapping option into the main build system and turns on stack smashing protection. diff --git a/Makefile b/Makefile index b802c63..78c31ab 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,15 @@ CDEBUGFLAGS = -Os -g -Wall # CDEBUGFLAGS = -Os -Wall # CDEBUGFLAGS = -g -Wall +# Add options to harden the build with specific gcc magic dust to help +# protect against buffer overflow exploits. SSP is available on gcc 4.1.2 +# and above. See: http://www.trl.ibm.com/projects/security/ssp/ +# +# _FORTIFY_SOURCE tells the C library to perform additional safety checks. +# +# CDEBUGFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all \ +# -Wstack-protector -fwrapv + # To compile on a pure POSIX system: # CC = c89 commit 817bd364275942381e37bf2111493de4769e319c Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Thu Dec 10 22:13:02 2009 +0200 Add an extra sanity check to avoid memmove segfault diff --git a/client.c b/client.c index 9d6e43c..86c6f20 100644 --- a/client.c +++ b/client.c @@ -998,7 +998,8 @@ httpClientDiscardBody(HTTPConnectionPtr connection) return 1; } - if(connection->reqlen > connection->reqbegin) { + if(connection->reqlen > connection->reqbegin && + (connection->reqlen - connection->reqbegin) > 0) { memmove(connection->reqbuf, connection->reqbuf + connection->reqbegin, connection->reqlen - connection->reqbegin); connection->reqlen -= connection->reqbegin;
commit 24d58b9b2da6efd9936737facb95f6eeca35b3af Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Fri Mar 19 12:47:28 2010 -0700 debug this diff --git a/Makefile b/Makefile index e6fd085..33fae90 100644 --- a/Makefile +++ b/Makefile @@ -23,8 +23,8 @@ CDEBUGFLAGS = -Os -g -Wall # # _FORTIFY_SOURCE tells the C library to perform additional safety checks. # -# CDEBUGFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all \ -# -Wstack-protector -fwrapv + CDEBUGFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all \ + -Wstack-protector -fwrapv -ansi -Wextra # To prevent some kinds of exploitation at run time, fix up the program's # got table to be read only (also reorders structures) after the first program commit 3311a08029d70f26e1c074da474d17e5ffd51a92 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sun Dec 27 16:20:51 2009 +0100 linker hardening diff --git a/Makefile b/Makefile index 78c31ab..e6fd085 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,11 @@ CDEBUGFLAGS = -Os -g -Wall # CDEBUGFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all \ # -Wstack-protector -fwrapv +# To prevent some kinds of exploitation at run time, fix up the program's +# got table to be read only (also reorders structures) after the first program +# load. eg: ld -z relro -z now +LDFLAGS += -z relro -z now + # To compile on a pure POSIX system: # CC = c89 commit eca86763b2b6d643c51d289b602c76b6a8637a46 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 16:16:41 2009 +0200 int fixups diff --git a/chunk.h b/chunk.h index 78d9743..c916a30 100644 --- a/chunk.h +++ b/chunk.h @@ -39,7 +39,7 @@ THE SOFTWARE. #define CHUNKS(bytes) ((unsigned long)(bytes) / CHUNK_SIZE) extern int chunkLowMark, chunkHighMark, chunkCriticalMark; -extern int used_chunks; +extern unsigned long used_chunks; void preinitChunks(void); void initChunks(void); commit 682a25eaa5255192aeb641d84041d1fb965900bc Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 16:08:15 2009 +0200 Cleanup ints for chunk.c This makes a few variables into unsigned ints diff --git a/chunk.c b/chunk.c index a11cc3f..0daef1d 100644 --- a/chunk.c +++ b/chunk.c @@ -93,11 +93,12 @@ initChunksCommon() } -int used_chunks = 0; +unsigned long used_chunks = 0; static void maybe_free_chunks(int arenas, int force) { + /* CHUNKS returns (unsigned long) */ if(force || used_chunks >= CHUNKS(chunkHighMark)) { discardObjects(force, force); } @@ -291,7 +292,7 @@ typedef struct _ChunkArena { } ChunkArenaRec, *ChunkArenaPtr; static ChunkArenaPtr chunkArenas, currentArena; -static int numArenas; +static unsigned int numArenas; #define CHUNK_IN_ARENA(chunk, arena) \ ((arena)->chunks && \ (char*)(chunk) >= (arena)->chunks && \ @@ -304,7 +305,7 @@ static int numArenas; void initChunks(void) { - int i; + unsigned int i; used_chunks = 0; initChunksCommon(); pagesize = getpagesize(); @@ -333,7 +334,7 @@ static ChunkArenaPtr findArena() { ChunkArenaPtr arena = NULL; - int i; + unsigned int i; for(i = 0; i < numArenas; i++) { arena = &(chunkArenas[i]); @@ -436,7 +437,8 @@ void free_chunk_arenas() { ChunkArenaPtr arena; - int i, rc; + unsigned int i; + int rc; for(i = 0; i < numArenas; i++) { arena = &(chunkArenas[i]); @@ -457,7 +459,7 @@ int totalChunkArenaSize() { ChunkArenaPtr arena; - int i, size = 0; + unsigned int i, size = 0; for(i = 0; i < numArenas; i++) { arena = &(chunkArenas[i]); commit 249e31733b39b667cef16f22b3708f0aef9986c4 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 15:47:49 2009 +0200 Ensure we're dealing with ints during our compares We want to ensure that we're always using ints for comparisions with ints. diff --git a/io.c b/io.c index a64bc81..2cc7c08 100644 --- a/io.c +++ b/io.c @@ -458,7 +458,7 @@ do_connect(AtomPtr addr, int index, int port, assert(addr->length > 0 && addr->string[0] == DNS_A); assert(addr->length % sizeof(HostAddressRec) == 1); - if(index >= (addr->length - 1)/ sizeof(HostAddressRec)) + if(index >= (addr->length - 1)/ (int)sizeof(HostAddressRec)) index = 0; request.firstindex = index; @@ -521,7 +521,7 @@ do_scheduled_connect(int status, FdEventHandlerPtr event) assert(addr->length > 0 && addr->string[0] == DNS_A); assert(addr->length % sizeof(HostAddressRec) == 1); - assert(request->index < (addr->length - 1) / sizeof(HostAddressRec)); + assert(request->index < (addr->length - 1) / (int)sizeof(HostAddressRec)); if(status) { done = request->handler(status, event, request); commit 4613aa15cd94c687a7a58fb4200868a7ce9c7865 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 15:46:01 2009 +0200 Make AtomPtr's length element an int It was an unsigned short but it was largely used with ints. diff --git a/atom.h b/atom.h index 0b9adeb..ee0b8ec 100644 --- a/atom.h +++ b/atom.h @@ -23,7 +23,7 @@ THE SOFTWARE. typedef struct _Atom { unsigned int refcount; struct _Atom *next; - unsigned short length; + int length; char string[1]; } AtomRec, *AtomPtr; commit 6eb6e906565edaec5785709a9bb788fc8b7d4857 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 15:31:31 2009 +0200 Check the return value of fwrite() We weren't checking the return value of fwrite(). It was possible that our logging would fail and we would never know. diff --git a/config.c b/config.c index 60d9ec5..eb24419 100644 --- a/config.c +++ b/config.c @@ -102,6 +102,7 @@ declareConfigVariable(AtomPtr name, int type, void *value, static void printString(FILE *out, char *string, int html) { + int r = 0; if(html) { char buf[512]; int i; @@ -110,7 +111,10 @@ printString(FILE *out, char *string, int html) fprintf(out, "(overflow)"); return; } - fwrite(buf, 1, i, out); + r = fwrite(buf, 1, i, out); + if (r != i) { + printf("String printing failure: wrote %d, expected %d\n", r, i); + } } else { fprintf(out, "%s", string); } commit aaa5b04ca33c2dc16316ec734760fca25148c1a1 Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Sat Dec 12 15:27:31 2009 +0200 Check the return value of fwrite() We weren't checking the return value of fwrite(). It was possible that our logging would fail and we would never know. diff --git a/log.c b/log.c index ec5c545..0f37771 100644 --- a/log.c +++ b/log.c @@ -470,9 +470,13 @@ really_do_log_error_v(int type, int e, const char *f, va_list args) void really_do_log_n(int type, const char *s, int n) { + int r = 0; if((type & LOGGING_MAX & logLevel) != 0) { if(logF) { - fwrite(s, n, 1, logF); + r = fwrite(s, n, 1, logF); + if (r != n) { + printf("Logging failure: wrote %d, expected %d\n", r, n); + } } #ifdef HAVE_SYSLOG if(logSyslog) commit 12f9f0d353322b6e0194722e5284666f8158e11a Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Thu Dec 10 22:17:07 2009 +0200 Add GCC-specific hardening flags to our Makefile. This adds support for fortified source, moves the integer wrapping option into the main build system and turns on stack smashing protection. diff --git a/Makefile b/Makefile index b802c63..78c31ab 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,15 @@ CDEBUGFLAGS = -Os -g -Wall # CDEBUGFLAGS = -Os -Wall # CDEBUGFLAGS = -g -Wall +# Add options to harden the build with specific gcc magic dust to help +# protect against buffer overflow exploits. SSP is available on gcc 4.1.2 +# and above. See: http://www.trl.ibm.com/projects/security/ssp/ +# +# _FORTIFY_SOURCE tells the C library to perform additional safety checks. +# +# CDEBUGFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all \ +# -Wstack-protector -fwrapv + # To compile on a pure POSIX system: # CC = c89 commit 817bd364275942381e37bf2111493de4769e319c Author: Jacob Appelbaum <ja...@appelbaum.net> Date: Thu Dec 10 22:13:02 2009 +0200 Add an extra sanity check to avoid memmove segfault diff --git a/client.c b/client.c index 9d6e43c..86c6f20 100644 --- a/client.c +++ b/client.c @@ -998,7 +998,8 @@ httpClientDiscardBody(HTTPConnectionPtr connection) return 1; } - if(connection->reqlen > connection->reqbegin) { + if(connection->reqlen > connection->reqbegin && + (connection->reqlen - connection->reqbegin) > 0) { memmove(connection->reqbuf, connection->reqbuf + connection->reqbegin, connection->reqlen - connection->reqbegin); connection->reqlen -= connection->reqbegin;
_______________________________________________ tails-dev mailing list tails-dev@boum.org https://mailman.boum.org/listinfo/tails-dev