From 78e38f59ad9f7fbb6a68a5f254aec7d9bae428c3 Mon Sep 17 00:00:00 2001
From: Ben Noordhuis <info@bnoordhuis.nl>
Date: Sat, 25 Oct 2014 07:27:21 +0200
Subject: [PATCH] src: fix uninitialized memory dereference

The elements of the heap-allocated TaskQueue::ring_ array in
src/node_v8_platform.cc were compared against without being
initialized first.

Fixes node-forward/node#33.

PR-URL: https://github.com/node-forward/node/pull/34
Reviewed-By: Fedor Indutny <fedor@indutny.com>
---
 src/node_v8_platform.cc | 14 ++++----------
 src/node_v8_platform.h  |  8 +++++---
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/src/node_v8_platform.cc b/src/node_v8_platform.cc
index d71fdd4cc9f..aed4661597b 100644
--- a/src/node_v8_platform.cc
+++ b/src/node_v8_platform.cc
@@ -98,12 +98,9 @@ void Platform::WorkerBody(void* arg) {
 TaskQueue::TaskQueue() {
   int err;
 
-  static_assert(kRingSize == (kRingSize & (~(kRingSize - 1))),
-                "kRingSize is not a power of two");
+  for (size_t i = 0; i < ARRAY_SIZE(ring_); i += 1)
+    ring_[i] = nullptr;
 
-  size_ = kRingSize;
-  ring_ = new Task*[size_];
-  mask_ = size_ - 1;
   read_off_ = 0;
   write_off_ = 0;
 
@@ -120,9 +117,6 @@ TaskQueue::TaskQueue() {
 
 TaskQueue::~TaskQueue() {
   CHECK_EQ(read_off_, write_off_);
-
-  delete[] ring_;
-  ring_ = nullptr;
   uv_sem_destroy(&sem_);
   uv_cond_destroy(&cond_);
   uv_mutex_destroy(&mutex_);
@@ -138,7 +132,7 @@ void TaskQueue::Push(Task* task) {
 
   ring_[write_off_] = task;
   write_off_++;
-  write_off_ &= mask_;
+  write_off_ &= kRingMask;
   uv_mutex_unlock(&mutex_);
 
   uv_sem_post(&sem_);
@@ -154,7 +148,7 @@ Task* TaskQueue::Shift() {
   uv_cond_signal(&cond_);
 
   read_off_++;
-  read_off_ &= mask_;
+  read_off_ &= kRingMask;
   uv_mutex_unlock(&mutex_);
 
   return task;
diff --git a/src/node_v8_platform.h b/src/node_v8_platform.h
index 59bcdaeb02d..a51c3a10a6c 100644
--- a/src/node_v8_platform.h
+++ b/src/node_v8_platform.h
@@ -37,15 +37,17 @@ class TaskQueue {
 
  private:
   static const unsigned int kRingSize = 1024;
+  static const unsigned int kRingMask = kRingSize - 1;
+
+  static_assert(kRingSize == (kRingSize & ~kRingMask),
+                "kRingSize is not a power of two");
 
   uv_sem_t sem_;
   uv_cond_t cond_;
   uv_mutex_t mutex_;
-  v8::Task** ring_;
-  unsigned int size_;
-  unsigned int mask_;
   unsigned int read_off_;
   unsigned int write_off_;
+  v8::Task* ring_[kRingSize];
 };
 
 class Platform : public v8::Platform {