You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/11/14 22:02:37 UTC

svn commit: r1714372 - in /subversion/trunk/subversion/libsvn_subr: cache-membuffer.c compress.c prefix_string.c skel.c spillbuf.c subst.c

Author: stefan2
Date: Sat Nov 14 21:02:37 2015
New Revision: 1714372

URL: http://svn.apache.org/viewvc?rev=1714372&view=rev
Log:
Fix a number of potential overflow conditions on platforms where pointers
may be allocated very close to the end of address space, such as WoW64.

Instead of "if (base + x < max)", we must use "if (max - base > x)" to
prevent overflows under all circumstances.

There is no direct way to use these to trigger a segfault on purpose,
rather a user might experience random crashes.  Due to the block sizes
we allocate and the fact that OS and RTL reserve the very top of the
address space, it is very unlikely to ever actually encounter an overflow
with valid lengths and offsets in SVN.

* subversion/libsvn_subr/cache-membuffer.c
  (ensure_data_insertable_l2,
   ensure_data_insertable_l1, 
   membuffer_cache_set_partial_internal): Fix the overflow check as
                                          indicated above.

* subversion/libsvn_subr/compress.c
  (svn__decode_uint): Same.

* subversion/libsvn_subr/prefix_string.c
  (svn_prefix_string__create): Same.

* subversion/libsvn_subr/skel.c
  (explicit_atom): Same.

* subversion/libsvn_subr/spillbuf.c
  (svn_spillbuf__write): Same.

* subversion/libsvn_subr/subst.c
  (translate_chunk): Same.

Modified:
    subversion/trunk/subversion/libsvn_subr/cache-membuffer.c
    subversion/trunk/subversion/libsvn_subr/compress.c
    subversion/trunk/subversion/libsvn_subr/prefix_string.c
    subversion/trunk/subversion/libsvn_subr/skel.c
    subversion/trunk/subversion/libsvn_subr/spillbuf.c
    subversion/trunk/subversion/libsvn_subr/subst.c

Modified: subversion/trunk/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/cache-membuffer.c?rev=1714372&r1=1714371&r2=1714372&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/trunk/subversion/libsvn_subr/cache-membuffer.c Sat Nov 14 21:02:37 2015
@@ -1665,7 +1665,7 @@ ensure_data_insertable_l2(svn_membuffer_
 
       /* leave function as soon as the insertion window is large enough
        */
-      if (end >= to_fit_in->size + cache->l2.current_data)
+      if (end - cache->l2.current_data >= to_fit_in->size)
         return TRUE;
 
       /* Don't be too eager to cache data.  If a lot of data has been moved
@@ -1790,7 +1790,7 @@ ensure_data_insertable_l1(svn_membuffer_
 
       /* leave function as soon as the insertion window is large enough
        */
-      if (end >= size + cache->l1.current_data)
+      if (end - cache->l1.current_data >= size)
         return TRUE;
 
       /* Enlarge the insertion window
@@ -2679,9 +2679,11 @@ membuffer_cache_set_partial_internal(svn
           if (item_data != orig_data)
             {
               /* Remove the old entry and try to make space for the new one.
+               * Note that the key has already been stored in the past, i.e.
+               * it is shorter than the MAX_ENTRY_SIZE.
                */
               drop_entry(cache, entry);
-              if (   (cache->max_entry_size >= item_size + key_len)
+              if (   (cache->max_entry_size - key_len >= item_size)
                   && ensure_data_insertable_l1(cache, item_size + key_len))
                 {
                   /* Write the new entry.

Modified: subversion/trunk/subversion/libsvn_subr/compress.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/compress.c?rev=1714372&r1=1714371&r2=1714372&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/compress.c (original)
+++ subversion/trunk/subversion/libsvn_subr/compress.c Sat Nov 14 21:02:37 2015
@@ -100,7 +100,7 @@ svn__decode_uint(apr_uint64_t *val,
 {
   apr_uint64_t temp = 0;
 
-  if (p + SVN__MAX_ENCODED_UINT_LEN < end)
+  if (end - p > SVN__MAX_ENCODED_UINT_LEN)
     end = p + SVN__MAX_ENCODED_UINT_LEN;
 
   /* Decode bytes until we're done. */

Modified: subversion/trunk/subversion/libsvn_subr/prefix_string.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/prefix_string.c?rev=1714372&r1=1714371&r2=1714372&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/prefix_string.c (original)
+++ subversion/trunk/subversion/libsvn_subr/prefix_string.c Sat Nov 14 21:02:37 2015
@@ -228,7 +228,7 @@ svn_prefix_string__create(svn_prefix_tre
     }
 
   /* add sub-node(s) and final string */
-  while (node->length + 7 < len)
+  while (len - node->length > 7)
     {
       new_node = apr_pcalloc(tree->pool, sizeof(*new_node));
       new_node->key.prefix = node;

Modified: subversion/trunk/subversion/libsvn_subr/skel.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/skel.c?rev=1714372&r1=1714371&r2=1714372&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/skel.c (original)
+++ subversion/trunk/subversion/libsvn_subr/skel.c Sat Nov 14 21:02:37 2015
@@ -380,7 +380,7 @@ explicit_atom(const char *data,
   data++;
 
   /* Check the length.  */
-  if (data + size > end)
+  if (end - data < size)
     return NULL;
 
   /* Allocate the skel representing this string.  */

Modified: subversion/trunk/subversion/libsvn_subr/spillbuf.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/spillbuf.c?rev=1714372&r1=1714371&r2=1714372&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/spillbuf.c (original)
+++ subversion/trunk/subversion/libsvn_subr/spillbuf.c Sat Nov 14 21:02:37 2015
@@ -242,7 +242,7 @@ svn_spillbuf__write(svn_spillbuf_t *buf,
      will grow too large. Create the file and place the pending data into
      the temporary file.  */
   if (buf->spill == NULL
-      && (buf->memory_size + len) > buf->maxsize)
+      && ((buf->maxsize - buf->memory_size) < len))
     {
       SVN_ERR(svn_io_open_unique_file3(&buf->spill,
                                        &buf->filename,

Modified: subversion/trunk/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/subst.c?rev=1714372&r1=1714371&r2=1714372&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/subst.c (original)
+++ subversion/trunk/subversion/libsvn_subr/subst.c Sat Nov 14 21:02:37 2015
@@ -1127,7 +1127,7 @@ translate_chunk(svn_stream_t *dst,
                 {
                   /* Check 4 bytes at once to allow for efficient pipelining
                     and to reduce loop condition overhead. */
-                  while ((p + len + 4) <= end)
+                  while ((end - p) >= (len + 4))
                     {
                       if (interesting[(unsigned char)p[len]]
                           || interesting[(unsigned char)p[len+1]]
@@ -1157,7 +1157,7 @@ translate_chunk(svn_stream_t *dst,
             }
           while (b->nl_translation_skippable ==
                    svn_tristate_true &&       /* can potentially skip EOLs */
-                 p + len + 2 < end &&         /* not too close to EOF */
+                 (end - p) > (len + 2) &&     /* not too close to EOF */
                  eol_unchanged(b, p + len));  /* EOL format already ok */
 
           while ((p + len) < end && !interesting[(unsigned char)p[len]])