[v8/el6: 1/2] nodejs 0.10.31/0.10.32 backport roundup

T.C. Hollingsworth patches at fedoraproject.org
Thu Sep 18 02:37:48 UTC 2014


commit 643e7db07d4b0d35d30650c025e1a0a99e7564f1
Author: T.C. Hollingsworth <tchollingsworth at gmail.com>
Date:   Wed Sep 17 19:35:04 2014 -0700

    nodejs 0.10.31/0.10.32 backport roundup
    
    - backport bugfix that eliminates unused-local-typedefs warning
    - backport security fix: Fix Hydrogen bounds check elimination (CVE-2013-6668; RHBZ#1086120)
    - backport fix to segfault caused by the above patch

 v8-3.14.5.10-CVE-2013-6668-segfault.patch    |   60 ++++++++
 v8-3.14.5.10-CVE-2013-6668.patch             |  186 ++++++++++++++++++++++++++
 v8-3.14.5.10-interrupts-stack-overflow.patch |   31 +++++
 v8-3.14.5.10-unused-local-typedefs.patch     |   39 ++++++
 v8.spec                                      |   24 +++-
 5 files changed, 339 insertions(+), 1 deletions(-)
---
diff --git a/v8-3.14.5.10-CVE-2013-6668-segfault.patch b/v8-3.14.5.10-CVE-2013-6668-segfault.patch
new file mode 100644
index 0000000..8e3d600
--- /dev/null
+++ b/v8-3.14.5.10-CVE-2013-6668-segfault.patch
@@ -0,0 +1,60 @@
+From 3122e0eae64c5ab494b29d0a9cadef902d93f1f9 Mon Sep 17 00:00:00 2001
+From: Fedor Indutny <fedor at indutny.com>
+Date: Fri, 22 Aug 2014 03:59:35 +0400
+Subject: [PATCH] deps: fix up v8 after fd80a3
+
+fd80a31e0697d6317ce8c2d289575399f4e06d21 has introduced a segfault
+during redundant boundary check elimination (#8208).
+
+The problem consists of two parts:
+
+  1. Abscense of instruction iterator in
+     `EliminateRedundantBoundsChecks`. It was present in recent v8, but
+     wasn't considered important at the time of backport. However, since
+     the function is changing instructions order in block, it is
+     important to not rely at `i->next()` at the end of the loop.
+  2. Too strict ASSERT in `MoveIndexIfNecessary`. It is essentially a
+     backport of a45c96ab from v8's upstream. See
+     https://github.com/v8/v8/commit/a45c96ab for details.
+
+fix #8208
+---
+ src/hydrogen.cc | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/src/hydrogen.cc b/src/hydrogen.cc
+index 50d8e49..18a6b60 100644
+--- a/src/hydrogen.cc
++++ b/src/hydrogen.cc
+@@ -3546,7 +3546,11 @@ class BoundsCheckBbData: public ZoneObject {
+   void MoveIndexIfNecessary(HValue* index_raw,
+                             HBoundsCheck* insert_before,
+                             HInstruction* end_of_scan_range) {
+-    ASSERT(index_raw->IsAdd() || index_raw->IsSub());
++    if (!index_raw->IsAdd() && !index_raw->IsSub()) {
++      // index_raw can be HAdd(index_base, offset), HSub(index_base, offset),
++      // or index_base directly. In the latter case, no need to move anything.
++      return;
++    }
+     HBinaryOperation* index =
+         HArithmeticBinaryOperation::cast(index_raw);
+     HValue* left_input = index->left();
+@@ -3581,7 +3585,6 @@ class BoundsCheckBbData: public ZoneObject {
+                     HBoundsCheck* tighter_check) {
+     ASSERT(original_check->length() == tighter_check->length());
+     MoveIndexIfNecessary(tighter_check->index(), original_check, tighter_check);
+-    original_check->ReplaceAllUsesWith(original_check->index());
+     original_check->SetOperandAt(0, tighter_check->index());
+   }
+ };
+@@ -3624,7 +3627,9 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
+                                             BoundsCheckTable* table) {
+   BoundsCheckBbData* bb_data_list = NULL;
+ 
+-  for (HInstruction* i = bb->first(); i != NULL; i = i->next()) {
++  HInstruction* next;
++  for (HInstruction* i = bb->first(); i != NULL; i = next) {
++    next = i->next();
+     if (!i->IsBoundsCheck()) continue;
+ 
+     HBoundsCheck* check = HBoundsCheck::cast(i);
diff --git a/v8-3.14.5.10-CVE-2013-6668.patch b/v8-3.14.5.10-CVE-2013-6668.patch
new file mode 100644
index 0000000..fe5cb6d
--- /dev/null
+++ b/v8-3.14.5.10-CVE-2013-6668.patch
@@ -0,0 +1,186 @@
+From fd80a31e0697d6317ce8c2d289575399f4e06d21 Mon Sep 17 00:00:00 2001
+From: Fedor Indutny <fedor at indutny.com>
+Date: Thu, 14 Aug 2014 19:29:28 +0400
+Subject: [PATCH] deps: backport 5f836c from v8 upstream
+
+Original commit message:
+
+    Fix Hydrogen bounds check elimination
+
+    When combining bounds checks, they must all be moved before the first load/store
+    that they are guarding.
+
+    BUG=chromium:344186
+    LOG=y
+    R=svenpanne at chromium.org
+
+    Review URL: https://codereview.chromium.org/172093002
+
+    git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@19475 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
+
+fix #8070
+---
+ src/hydrogen.cc | 106 +++++++++++++++++++++++-------------------------
+ 1 file changed, 50 insertions(+), 56 deletions(-)
+
+diff --git a/src/hydrogen.cc b/src/hydrogen.cc
+index e3f79ee..50d8e49 100644
+--- a/src/hydrogen.cc
++++ b/src/hydrogen.cc
+@@ -3487,13 +3487,7 @@ class BoundsCheckBbData: public ZoneObject {
+         keep_new_check = true;
+         upper_check_ = new_check;
+       } else {
+-        BuildOffsetAdd(upper_check_,
+-                       &added_upper_index_,
+-                       &added_upper_offset_,
+-                       Key()->IndexBase(),
+-                       new_check->index()->representation(),
+-                       new_offset);
+-        upper_check_->SetOperandAt(0, added_upper_index_);
++        TightenCheck(upper_check_, new_check);
+       }
+     } else if (new_offset < lower_offset_) {
+       lower_offset_ = new_offset;
+@@ -3501,28 +3495,27 @@ class BoundsCheckBbData: public ZoneObject {
+         keep_new_check = true;
+         lower_check_ = new_check;
+       } else {
+-        BuildOffsetAdd(lower_check_,
+-                       &added_lower_index_,
+-                       &added_lower_offset_,
+-                       Key()->IndexBase(),
+-                       new_check->index()->representation(),
+-                       new_offset);
+-        lower_check_->SetOperandAt(0, added_lower_index_);
++        TightenCheck(lower_check_, new_check);
+       }
+     } else {
+-      ASSERT(false);
++      // Should never have called CoverCheck() in this case.
++      UNREACHABLE();
+     }
+ 
+     if (!keep_new_check) {
+       new_check->DeleteAndReplaceWith(NULL);
++    } else {
++      HBoundsCheck* first_check = new_check == lower_check_ ? upper_check_
++                                                            : lower_check_;
++      // The length is guaranteed to be live at first_check.
++      ASSERT(new_check->length() == first_check->length());
++      HInstruction* old_position = new_check->next();
++      new_check->Unlink();
++      new_check->InsertAfter(first_check);
++      MoveIndexIfNecessary(new_check->index(), new_check, old_position);
+     }
+   }
+ 
+-  void RemoveZeroOperations() {
+-    RemoveZeroAdd(&added_lower_index_, &added_lower_offset_);
+-    RemoveZeroAdd(&added_upper_index_, &added_upper_offset_);
+-  }
+-
+   BoundsCheckBbData(BoundsCheckKey* key,
+                     int32_t lower_offset,
+                     int32_t upper_offset,
+@@ -3537,10 +3530,6 @@ class BoundsCheckBbData: public ZoneObject {
+     basic_block_(bb),
+     lower_check_(lower_check),
+     upper_check_(upper_check),
+-    added_lower_index_(NULL),
+-    added_lower_offset_(NULL),
+-    added_upper_index_(NULL),
+-    added_upper_offset_(NULL),
+     next_in_bb_(next_in_bb),
+     father_in_dt_(father_in_dt) { }
+ 
+@@ -3551,44 +3540,50 @@ class BoundsCheckBbData: public ZoneObject {
+   HBasicBlock* basic_block_;
+   HBoundsCheck* lower_check_;
+   HBoundsCheck* upper_check_;
+-  HAdd* added_lower_index_;
+-  HConstant* added_lower_offset_;
+-  HAdd* added_upper_index_;
+-  HConstant* added_upper_offset_;
+   BoundsCheckBbData* next_in_bb_;
+   BoundsCheckBbData* father_in_dt_;
+ 
+-  void BuildOffsetAdd(HBoundsCheck* check,
+-                      HAdd** add,
+-                      HConstant** constant,
+-                      HValue* original_value,
+-                      Representation representation,
+-                      int32_t new_offset) {
+-    HConstant* new_constant = new(BasicBlock()->zone())
+-       HConstant(new_offset, Representation::Integer32());
+-    if (*add == NULL) {
+-      new_constant->InsertBefore(check);
+-      // Because of the bounds checks elimination algorithm, the index is always
+-      // an HAdd or an HSub here, so we can safely cast to an HBinaryOperation.
+-      HValue* context = HBinaryOperation::cast(check->index())->context();
+-      *add = new(BasicBlock()->zone()) HAdd(context,
+-                                            original_value,
+-                                            new_constant);
+-      (*add)->AssumeRepresentation(representation);
+-      (*add)->InsertBefore(check);
+-    } else {
+-      new_constant->InsertBefore(*add);
+-      (*constant)->DeleteAndReplaceWith(new_constant);
++  void MoveIndexIfNecessary(HValue* index_raw,
++                            HBoundsCheck* insert_before,
++                            HInstruction* end_of_scan_range) {
++    ASSERT(index_raw->IsAdd() || index_raw->IsSub());
++    HBinaryOperation* index =
++        HArithmeticBinaryOperation::cast(index_raw);
++    HValue* left_input = index->left();
++    HValue* right_input = index->right();
++    bool must_move_index = false;
++    bool must_move_left_input = false;
++    bool must_move_right_input = false;
++    for (HInstruction* cursor = end_of_scan_range; cursor != insert_before;) {
++      if (cursor == left_input) must_move_left_input = true;
++      if (cursor == right_input) must_move_right_input = true;
++      if (cursor == index) must_move_index = true;
++      if (cursor->previous() == NULL) {
++        cursor = cursor->block()->dominator()->end();
++      } else {
++        cursor = cursor->previous();
++      }
+     }
+-    *constant = new_constant;
+-  }
+ 
+-  void RemoveZeroAdd(HAdd** add, HConstant** constant) {
+-    if (*add != NULL && (*constant)->Integer32Value() == 0) {
+-      (*add)->DeleteAndReplaceWith((*add)->left());
+-      (*constant)->DeleteAndReplaceWith(NULL);
++    // The BCE algorithm only selects mergeable bounds checks that share
++    // the same "index_base", so we'll only ever have to move constants.
++    if (must_move_left_input) {
++      HConstant::cast(left_input)->Unlink();
++      HConstant::cast(left_input)->InsertBefore(index);
++    }
++    if (must_move_right_input) {
++      HConstant::cast(right_input)->Unlink();
++      HConstant::cast(right_input)->InsertBefore(index);
+     }
+   }
++
++  void TightenCheck(HBoundsCheck* original_check,
++                    HBoundsCheck* tighter_check) {
++    ASSERT(original_check->length() == tighter_check->length());
++    MoveIndexIfNecessary(tighter_check->index(), original_check, tighter_check);
++    original_check->ReplaceAllUsesWith(original_check->index());
++    original_check->SetOperandAt(0, tighter_check->index());
++  }
+ };
+ 
+ 
+@@ -3683,7 +3678,6 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
+   for (BoundsCheckBbData* data = bb_data_list;
+        data != NULL;
+        data = data->NextInBasicBlock()) {
+-    data->RemoveZeroOperations();
+     if (data->FatherInDominatorTree()) {
+       table->Insert(data->Key(), data->FatherInDominatorTree(), zone());
+     } else {
diff --git a/v8-3.14.5.10-interrupts-stack-overflow.patch b/v8-3.14.5.10-interrupts-stack-overflow.patch
new file mode 100644
index 0000000..049b4df
--- /dev/null
+++ b/v8-3.14.5.10-interrupts-stack-overflow.patch
@@ -0,0 +1,31 @@
+From 530af9cb8e700e7596b3ec812bad123c9fa06356 Mon Sep 17 00:00:00 2001
+From: Fedor Indutny <fedor at indutny.com>
+Date: Wed, 30 Jul 2014 15:33:52 -0700
+Subject: [PATCH] v8: Interrupts must not mask stack overflow.
+
+Backport of https://codereview.chromium.org/339883002
+---
+ src/isolate.h | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/src/isolate.h b/src/isolate.h
+index b90191d..2769ca7 100644
+--- a/src/isolate.h
++++ b/src/isolate.h
+@@ -1392,14 +1392,9 @@ class StackLimitCheck BASE_EMBEDDED {
+  public:
+   explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }
+ 
+-  bool HasOverflowed() const {
++  inline bool HasOverflowed() const {
+     StackGuard* stack_guard = isolate_->stack_guard();
+-    // Stack has overflowed in C++ code only if stack pointer exceeds the C++
+-    // stack guard and the limits are not set to interrupt values.
+-    // TODO(214): Stack overflows are ignored if a interrupt is pending. This
+-    // code should probably always use the initial C++ limit.
+-    return (reinterpret_cast<uintptr_t>(this) < stack_guard->climit()) &&
+-           stack_guard->IsStackOverflow();
++    return reinterpret_cast<uintptr_t>(this) < stack_guard->real_climit();
+   }
+  private:
+   Isolate* isolate_;
diff --git a/v8-3.14.5.10-unused-local-typedefs.patch b/v8-3.14.5.10-unused-local-typedefs.patch
new file mode 100644
index 0000000..c168875
--- /dev/null
+++ b/v8-3.14.5.10-unused-local-typedefs.patch
@@ -0,0 +1,39 @@
+From 53b4accb6e5747b156be91a2b90f42607e33a7cc Mon Sep 17 00:00:00 2001
+From: Timothy J Fontaine <tjfontaine at gmail.com>
+Date: Mon, 4 Aug 2014 13:43:50 -0700
+Subject: [PATCH] v8: Fix compliation with GCC 4.8
+
+Supresses a very loud warning from GCC 4.8 about unused typedefs
+
+Original url https://codereview.chromium.org/69413002
+---
+ src/checks.h | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/src/checks.h b/src/checks.h
+index d0a0c2b..4396ada 100644
+--- a/src/checks.h
++++ b/src/checks.h
+@@ -230,6 +230,13 @@ inline void CheckNonEqualsHelper(const char* file,
+ #define CHECK_LE(a, b) CHECK((a) <= (b))
+ 
+ 
++#if defined(__clang__) || defined(__GNUC__)
++# define V8_UNUSED __attribute__((unused))                                                                                                                                                                         
++#else                                                                                                                                                                                                              
++# define V8_UNUSED                                                                                                                                                                                                 
++#endif
++
++
+ // This is inspired by the static assertion facility in boost.  This
+ // is pretty magical.  If it causes you trouble on a platform you may
+ // find a fix in the boost code.
+@@ -248,7 +255,7 @@ template <int> class StaticAssertionHelper { };
+ #define STATIC_CHECK(test)                                                    \
+   typedef                                                                     \
+     StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)> \
+-    SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__)
++    SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__) V8_UNUSED
+ 
+ 
+ extern bool FLAG_enable_slow_asserts;
diff --git a/v8.spec b/v8.spec
index 83a36fb..ebbefd6 100644
--- a/v8.spec
+++ b/v8.spec
@@ -79,6 +79,20 @@ Patch9:     v8-3.14.5.10-mem-corruption-stack-overflow.patch
 # https://github.com/joyent/node/commit/3530fa9cd09f8db8101c4649cab03bcdf760c434
 Patch10:    v8-3.14.5.10-x64-MathMinMax.patch
 
+# backport bugfix that eliminates unused-local-typedefs warning
+# https://github.com/joyent/node/commit/53b4accb6e5747b156be91a2b90f42607e33a7cc
+Patch11:    v8-3.14.5.10-unused-local-typedefs.patch
+
+# backport security fix: Fix Hydrogen bounds check elimination
+# resolves CVE-2013-6668 (RHBZ#1086120)
+# https://github.com/joyent/node/commit/fd80a31e0697d6317ce8c2d289575399f4e06d21
+Patch12:    v8-3.14.5.10-CVE-2013-6668.patch
+
+# backport fix to segfault caused by the above patch
+# https://github.com/joyent/node/commit/3122e0eae64c5ab494b29d0a9cadef902d93f1f9
+Patch13:    v8-3.14.5.10-CVE-2013-6668-segfault.patch
+
+
 %description
 V8 is Google's open source JavaScript engine. V8 is written in C++ and is used 
 in Google Chrome, the open source browser from Google. V8 implements ECMAScript 
@@ -104,6 +118,9 @@ Development headers and libraries for v8.
 %patch8 -p1
 %patch9 -p1
 %patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
 
 #Patch7 needs -lrt on glibc < 2.17 (RHEL <= 6)
 %if (0%{?rhel} > 6 || 0%{?fedora} > 18)
@@ -113,7 +130,7 @@ Development headers and libraries for v8.
 %endif
 
 # -fno-strict-aliasing is needed with gcc 4.4 to get past some ugly code
-PARSED_OPT_FLAGS=`echo \'$RPM_OPT_FLAGS %{lrt} -fPIC -fno-strict-aliasing -Wno-unused-parameter -Wno-error=strict-overflow -Wno-error=unused-local-typedefs -Wno-unused-but-set-variable\'| sed "s/ /',/g" | sed "s/',/', '/g"`
+PARSED_OPT_FLAGS=`echo \'$RPM_OPT_FLAGS %{lrt} -fPIC -fno-strict-aliasing -Wno-unused-parameter -Wno-error=strict-overflow -Wno-unused-but-set-variable\'| sed "s/ /',/g" | sed "s/',/', '/g"`
 sed -i "s|'-O3',|$PARSED_OPT_FLAGS,|g" SConstruct
 
 # clear spurious executable bits
@@ -268,6 +285,11 @@ rm -rf %{buildroot}
 %{python_sitelib}/j*.py*
 
 %changelog
+* Wed Sep 17 2014 T.C. Hollingsworth <tchollingsworth at gmail.com> - 1:3.14.5.10-12
+- backport bugfix that eliminates unused-local-typedefs warning
+- backport security fix: Fix Hydrogen bounds check elimination (CVE-2013-6668; RHBZ#1086120)
+- backport fix to segfault caused by the above patch
+
 * Thu Jul 31 2014 T.C. Hollingsworth <tchollingsworth at gmail.com> - 1:3.14.5.10-11
 - backport security fix for memory corruption and stack overflow (RHBZ#1125464)
   https://groups.google.com/d/msg/nodejs/-siJEObdp10/2xcqqmTHiEMJ


More information about the scm-commits mailing list