Bug 1059813: Protect access to fields of |UnixSocketRawData|, r=qdot
☠☠ backed out by 927da4815ef9 ☠ ☠
authorThomas Zimmermann <tdz@users.sourceforge.net>
Wed, 03 Sep 2014 16:43:14 +0200
changeset 203197 cffeecd46cade055f3762b4a9ab2fb0bbe34ce70
parent 203196 f991f546dbcdc00086d3cebbbd7a06232204e088
child 203198 142047b2389e5f9b6037a9b27e08666840ed7271
push id27423
push userryanvm@gmail.com
push dateWed, 03 Sep 2014 18:53:23 +0000
treeherdermozilla-central@117271830c4d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqdot
bugs1059813
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1059813: Protect access to fields of |UnixSocketRawData|, r=qdot This patch adds protection for fields of |UnixSocketRawData| by making them private.
ipc/unixsocket/SocketBase.cpp
ipc/unixsocket/SocketBase.h
--- a/ipc/unixsocket/SocketBase.cpp
+++ b/ipc/unixsocket/SocketBase.cpp
@@ -13,49 +13,49 @@
 
 namespace mozilla {
 namespace ipc {
 
 //
 // UnixSocketRawData
 //
 
-UnixSocketRawData::UnixSocketRawData(size_t aSize)
-: mSize(0)
-, mCurrentWriteOffset(0)
-, mAvailableSpace(aSize)
-{
-  mData = new uint8_t[mAvailableSpace];
-}
-
 UnixSocketRawData::UnixSocketRawData(const void* aData, size_t aSize)
 : mSize(aSize)
-, mCurrentWriteOffset(0)
+, mOffset(0)
 , mAvailableSpace(aSize)
 {
   MOZ_ASSERT(aData || !mSize);
 
   mData = new uint8_t[mAvailableSpace];
   memcpy(mData, aData, mSize);
 }
 
+UnixSocketRawData::UnixSocketRawData(size_t aSize)
+: mSize(0)
+, mOffset(0)
+, mAvailableSpace(aSize)
+{
+  mData = new uint8_t[mAvailableSpace];
+}
+
 nsresult
 UnixSocketRawData::Receive(int aFd)
 {
   if (!GetTrailingSpace()) {
     if (!GetLeadingSpace()) {
       return NS_ERROR_OUT_OF_MEMORY; /* buffer is full */
     }
     /* free up space at the end of data buffer */
     if (GetSize() <= GetLeadingSpace()) {
       memcpy(mData, GetData(), GetSize());
     } else {
       memmove(mData, GetData(), GetSize());
     }
-    mCurrentWriteOffset = 0;
+    mOffset = 0;
   }
 
   ssize_t res =
     TEMP_FAILURE_RETRY(read(aFd, GetTrailingBytes(), GetTrailingSpace()));
 
   if (res < 0) {
     if (errno == EAGAIN || errno == EWOULDBLOCK) {
       return NS_OK; /* no more data available; try again later */
@@ -190,17 +190,17 @@ SocketConsumerBase::SetConnectionStatus(
 //
 
 SocketIOBase::~SocketIOBase()
 { }
 
 void
 SocketIOBase::EnqueueData(UnixSocketRawData* aData)
 {
-  if (!aData->mSize) {
+  if (!aData->GetSize()) {
     delete aData; // delete empty data immediately
     return;
   }
   mOutgoingQ.AppendElement(aData);
 }
 
 bool
 SocketIOBase::HasPendingData() const
--- a/ipc/unixsocket/SocketBase.h
+++ b/ipc/unixsocket/SocketBase.h
@@ -24,77 +24,74 @@ namespace ipc {
 
 //
 // UnixSocketRawData
 //
 
 class UnixSocketRawData
 {
 public:
-  // Number of octets in mData.
-  size_t mSize;
-  size_t mCurrentWriteOffset;
-  nsAutoArrayPtr<uint8_t> mData;
 
-  /**
-   * Constructor for situations where only size is known beforehand
-   * (for example, when being assigned strings)
+  /* This constructor copies aData of aSize bytes length into the
+   * new instance of |UnixSocketRawData|.
+   */
+  UnixSocketRawData(const void* aData, size_t aSize);
+
+  /* This constructor reserves aSize bytes of space. Currently
+   * it's only possible to fill this buffer by calling |Receive|.
    */
   UnixSocketRawData(size_t aSize);
 
-  /**
-   * Constructor for situations where size and data is known
-   * beforehand (for example, when being assigned strings)
-   */
-  UnixSocketRawData(const void* aData, size_t aSize);
-
   nsresult Receive(int aFd);
   nsresult Send(int aFd);
 
   const uint8_t* GetData() const
   {
-    return mData + mCurrentWriteOffset;
+    return mData + mOffset;
   }
 
   size_t GetSize() const
   {
     return mSize;
   }
 
   void Consume(size_t aSize)
   {
     MOZ_ASSERT(aSize <= mSize);
 
     mSize -= aSize;
-    mCurrentWriteOffset += aSize;
+    mOffset += aSize;
   }
 
 protected:
   size_t GetLeadingSpace() const
   {
-    return mCurrentWriteOffset;
+    return mOffset;
   }
 
   size_t GetTrailingSpace() const
   {
-    return mAvailableSpace - (mCurrentWriteOffset + mSize);
+    return mAvailableSpace - (mOffset + mSize);
   }
 
   size_t GetAvailableSpace() const
   {
     return mAvailableSpace;
   }
 
   void* GetTrailingBytes()
   {
-    return mData + mCurrentWriteOffset + mSize;
+    return mData + mOffset + mSize;
   }
 
 private:
+  size_t mSize;
+  size_t mOffset;
   size_t mAvailableSpace;
+  nsAutoArrayPtr<uint8_t> mData;
 };
 
 enum SocketConnectionStatus {
   SOCKET_DISCONNECTED = 0,
   SOCKET_LISTENING = 1,
   SOCKET_CONNECTING = 2,
   SOCKET_CONNECTED = 3
 };