diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-11 07:17:19 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-11 07:17:19 +0000 |
commit | 6383fb7ccbdb2a9888031eb8a81b06403bb5d1a6 (patch) | |
tree | ca082bfb6e6da0dc0c18a7d1c52fb02b632aafce /remoting/base | |
parent | 3c1adb8d65f34181408fa548503e9b7222bb2d74 (diff) | |
download | chromium_src-6383fb7ccbdb2a9888031eb8a81b06403bb5d1a6.zip chromium_src-6383fb7ccbdb2a9888031eb8a81b06403bb5d1a6.tar.gz chromium_src-6383fb7ccbdb2a9888031eb8a81b06403bb5d1a6.tar.bz2 |
Launch the host under LocalService account at low integrity level with all privileges removed. It receives it's own window station and desktop only accessible by SYSTEM and logon SID the host process is running under. The security descriptor assigned to th eprocess gives access to SYSTEM and limited (query and terminate) access to built-in administrators group.
BUG=134694
Review URL: https://chromiumcodereview.appspot.com/11428172
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@172268 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/base')
-rw-r--r-- | remoting/base/typed_buffer.h | 98 | ||||
-rw-r--r-- | remoting/base/typed_buffer_unittest.cc | 101 |
2 files changed, 199 insertions, 0 deletions
diff --git a/remoting/base/typed_buffer.h b/remoting/base/typed_buffer.h new file mode 100644 index 0000000..c80f720 --- /dev/null +++ b/remoting/base/typed_buffer.h @@ -0,0 +1,98 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_BASE_TYPED_BUFFER_H_ +#define REMOTING_BASE_TYPED_BUFFER_H_ + +#include <assert.h> + +#include <algorithm> + +#include "base/basictypes.h" +#include "base/move.h" + +namespace remoting { + +// A scoper for a variable-length structure such as SID, SECURITY_DESCRIPTOR and +// similar. These structures typically consist of a header followed by variable- +// length data, so the size may not match sizeof(T). The class supports +// move-only semantics and typed buffer getters. +template <typename T> +class TypedBuffer { + MOVE_ONLY_TYPE_FOR_CPP_03(TypedBuffer, RValue) + + public: + TypedBuffer() : buffer_(NULL), length_(0) { + } + + // Creates an instance of the object allocating a buffer of the given size. + explicit TypedBuffer(uint32 length) : buffer_(NULL), length_(length) { + if (length_ > 0) + buffer_ = reinterpret_cast<T*>(new uint8[length_]); + } + + // Move constructor for C++03 move emulation of this type. + TypedBuffer(RValue rvalue) : buffer_(NULL), length_(0) { + TypedBuffer temp; + temp.Swap(*rvalue.object); + Swap(temp); + } + + ~TypedBuffer() { + if (buffer_) { + delete[] reinterpret_cast<uint8*>(buffer_); + buffer_ = NULL; + } + } + + // Move operator= for C++03 move emulation of this type. + TypedBuffer& operator=(RValue rvalue) { + TypedBuffer temp; + temp.Swap(*rvalue.object); + Swap(temp); + return *this; + } + + // Accessors to get the owned buffer. + // operator* and operator-> will assert() if there is no current buffer. + T& operator*() const { + assert(buffer_ != NULL); + return *buffer_; + } + T* operator->() const { + assert(buffer_ != NULL); + return buffer_; + } + T* get() const { return buffer_; } + + uint32 length() const { return length_; } + + // Helper returning a pointer to the structure starting at a specified byte + // offset. + T* GetAtOffset(uint32 offset) { + return reinterpret_cast<T*>(reinterpret_cast<uint8*>(buffer_) + offset); + } + + // Allow TypedBuffer<T> to be used in boolean expressions, but not + // implicitly convertible to a real bool (which is dangerous). + typedef T* TypedBuffer::*Testable; + operator Testable() const { return buffer_ ? &TypedBuffer::buffer_ : NULL; } + + // Swap two buffers. + void Swap(TypedBuffer& other) { + std::swap(buffer_, other.buffer_); + std::swap(length_, other.length_); + } + + private: + // Points to the owned buffer. + T* buffer_; + + // Length of the owned buffer in bytes. + uint32 length_; +}; + +} // namespace remoting + +#endif // REMOTING_BASE_TYPED_BUFFER_H_ diff --git a/remoting/base/typed_buffer_unittest.cc b/remoting/base/typed_buffer_unittest.cc new file mode 100644 index 0000000..0c036fb --- /dev/null +++ b/remoting/base/typed_buffer_unittest.cc @@ -0,0 +1,101 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/base/typed_buffer.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace remoting { + +namespace { + +struct Data { + // A variable size vector. + int data[1]; +}; + +} // namespace + +// Check that the default constructor does not allocate the buffer. +TEST(TypedBufferTest, Empty) { + TypedBuffer<Data> buffer; + EXPECT_FALSE(buffer.get()); + EXPECT_FALSE(buffer); + EXPECT_EQ(buffer.length(), 0u); +} + +// Check that allocating zero-size structure does not allocate the buffer. +TEST(TypedBufferTest, ZeroSize) { + TypedBuffer<Data> buffer(0); + EXPECT_FALSE(buffer.get()); + EXPECT_FALSE(buffer); + EXPECT_EQ(buffer.length(), 0u); +} + +// Test creation of a buffer and verify that the buffer accessors work. +TEST(TypedBufferTest, Basic) { + TypedBuffer<Data> buffer(sizeof(int) * 10); + EXPECT_TRUE(buffer.get()); + EXPECT_TRUE(buffer); + EXPECT_EQ(buffer.length(), sizeof(int) * 10); + + // Make sure that operator*() syntax works. + (*buffer).data[9] = 0x12345678; + + // Make sure that operator->() syntax works. + EXPECT_EQ(buffer->data[9], 0x12345678); +} + +// Test passing ownership. +TEST(TypedBufferTest, Pass) { + TypedBuffer<Data> left; + TypedBuffer<Data> right(sizeof(int)); + + EXPECT_FALSE(left.get()); + EXPECT_EQ(left.length(), 0u); + EXPECT_TRUE(right.get()); + EXPECT_EQ(right.length(), sizeof(int)); + + Data* raw_ptr = right.get(); + left = right.Pass(); + + // Verify that passing ownership transfers both the buffer pointer and its + // length. + EXPECT_EQ(left.get(), raw_ptr); + EXPECT_EQ(left.length(), sizeof(int)); + + // Verify that the original object was cleared. + EXPECT_FALSE(right.get()); + EXPECT_EQ(right.length(), 0u); +} + +// Test swapping ownership. +TEST(TypedBufferTest, Swap) { + TypedBuffer<Data> left(sizeof(int)); + TypedBuffer<Data> right(sizeof(int) * 2); + + EXPECT_TRUE(left.get()); + EXPECT_EQ(left.length(), sizeof(int)); + EXPECT_TRUE(right.get()); + EXPECT_EQ(right.length(), sizeof(int) * 2); + + Data* raw_left = left.get(); + Data* raw_right = right.get(); + left.Swap(right); + + // Verify that swapping simply exchange contents of two objects. + // length. + EXPECT_EQ(left.get(), raw_right); + EXPECT_EQ(left.length(), sizeof(int) * 2); + EXPECT_EQ(right.get(), raw_left); + EXPECT_EQ(right.length(), sizeof(int)); +} + +TEST(TypedBufferTest, GetAtOffset) { + TypedBuffer<Data> buffer(sizeof(int) * 10); + EXPECT_EQ(buffer.get(), buffer.GetAtOffset(0)); + EXPECT_EQ(reinterpret_cast<Data*>(&buffer->data[9]), + buffer.GetAtOffset(sizeof(int) * 9)); +} + +} // namespace remoting |