Patch below fixes https://trac.torproject.org/projects/tor/ticket/20384
for 6.0-stable.  Tested on powerpc.


Index: Makefile
===================================================================
RCS file: /cvs/ports/net/tor/Makefile,v
retrieving revision 1.90
diff -u -p -r1.90 Makefile
--- Makefile    18 May 2016 10:14:07 -0000      1.90
+++ Makefile    19 Oct 2016 12:16:44 -0000
@@ -5,7 +5,7 @@ COMMENT=        anonymity service using onion r
 DISTNAME=      tor-0.2.7.6
 CATEGORIES=    net
 HOMEPAGE=      https://www.torproject.org/
-REVISION=      1
+REVISION=      2
 
 MAINTAINER=    Pascal Stumpf <pas...@stumpf.co>
 
Index: patches/patch-src_or_buffers_c
===================================================================
RCS file: patches/patch-src_or_buffers_c
diff -N patches/patch-src_or_buffers_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_or_buffers_c      19 Oct 2016 12:16:44 -0000
@@ -0,0 +1,86 @@
+$OpenBSD$
+
+From: Nick Mathewson <ni...@torproject.org>
+Date: Fri, 14 Oct 2016 09:38:12 -0400
+Subject: [PATCH] Add a one-word sentinel value of 0x0 at the end of each buf_t
+ chunk
+
+This helps protect against bugs where any part of a buf_t's memory
+is passed to a function that expects a NUL-terminated input.
+
+It also closes TROVE-2016-10-001 (aka bug 20384).
+
+--- src/or/buffers.c.orig      Fri Nov 13 14:33:26 2015
++++ src/or/buffers.c   Wed Oct 19 13:52:55 2016
+@@ -69,13 +69,34 @@ static int parse_socks_client(const uint8_t *data, siz
+ 
+ #define CHUNK_HEADER_LEN STRUCT_OFFSET(chunk_t, mem[0])
+ 
++/* We leave this many NUL bytes at the end of the buffer. */
++#define SENTINEL_LEN 4
++
++/* Header size plus NUL bytes at the end */
++#define CHUNK_OVERHEAD (CHUNK_HEADER_LEN + SENTINEL_LEN)
++
+ /** Return the number of bytes needed to allocate a chunk to hold
+  * <b>memlen</b> bytes. */
+-#define CHUNK_ALLOC_SIZE(memlen) (CHUNK_HEADER_LEN + (memlen))
++#define CHUNK_ALLOC_SIZE(memlen) (CHUNK_OVERHEAD + (memlen))
+ /** Return the number of usable bytes in a chunk allocated with
+  * malloc(<b>memlen</b>). */
+-#define CHUNK_SIZE_WITH_ALLOC(memlen) ((memlen) - CHUNK_HEADER_LEN)
++#define CHUNK_SIZE_WITH_ALLOC(memlen) ((memlen) - CHUNK_OVERHEAD)
+ 
++#define DEBUG_SENTINEL
++
++#ifdef DEBUG_SENTINEL
++#define DBG_S(s) s
++#else
++#define DBG_S(s) (void)0
++#endif
++
++#define CHUNK_SET_SENTINEL(chunk, alloclen) do {                        \
++    uint8_t *a = (uint8_t*) &(chunk)->mem[(chunk)->memlen];             \
++    DBG_S(uint8_t *b = &((uint8_t*)(chunk))[(alloclen)-SENTINEL_LEN]);  \
++    DBG_S(tor_assert(a == b));                                          \
++    memset(a,0,SENTINEL_LEN);                                           \
++  } while (0)
++
+ /** Return the next character in <b>chunk</b> onto which data can be appended.
+  * If the chunk is full, this might be off the end of chunk->mem. */
+ static INLINE char *
+@@ -131,6 +152,7 @@ chunk_new_with_alloc_size(size_t alloc)
+   ch->memlen = CHUNK_SIZE_WITH_ALLOC(alloc);
+   total_bytes_allocated_in_chunks += alloc;
+   ch->data = &ch->mem[0];
++  CHUNK_SET_SENTINEL(ch, alloc);
+   return ch;
+ }
+ 
+@@ -140,18 +162,20 @@ static INLINE chunk_t *
+ chunk_grow(chunk_t *chunk, size_t sz)
+ {
+   off_t offset;
+-  size_t memlen_orig = chunk->memlen;
++  const size_t memlen_orig = chunk->memlen;
++  const size_t orig_alloc = CHUNK_ALLOC_SIZE(memlen_orig);
++  const size_t new_alloc = CHUNK_ALLOC_SIZE(sz);
+   tor_assert(sz > chunk->memlen);
+   offset = chunk->data - chunk->mem;
+-  chunk = tor_realloc(chunk, CHUNK_ALLOC_SIZE(sz));
++  chunk = tor_realloc(chunk, new_alloc);
+   chunk->memlen = sz;
+   chunk->data = chunk->mem + offset;
+ #ifdef DEBUG_CHUNK_ALLOC
+-  tor_assert(chunk->DBG_alloc == CHUNK_ALLOC_SIZE(memlen_orig));
+-  chunk->DBG_alloc = CHUNK_ALLOC_SIZE(sz);
++  tor_assert(chunk->DBG_alloc == orig_alloc);
++  chunk->DBG_alloc = new_alloc;
+ #endif
+-  total_bytes_allocated_in_chunks +=
+-    CHUNK_ALLOC_SIZE(sz) - CHUNK_ALLOC_SIZE(memlen_orig);
++  total_bytes_allocated_in_chunks += new_alloc - orig_alloc;
++  CHUNK_SET_SENTINEL(chunk, new_alloc);
+   return chunk;
+ }
+ 

Reply via email to