diff options
27 files changed, 143 insertions, 248 deletions
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index b713f82..cbb47dd 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc @@ -402,6 +402,15 @@ bool ChromeContentClient::SandboxPlugin(CommandLine* command_line, return false; } + // Add policy for the plugin proxy window pump event + // used by WebPluginDelegateProxy::HandleInputEvent(). + if (policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, + sandbox::TargetPolicy::HANDLES_DUP_ANY, + L"Event") != sandbox::SBOX_ALL_OK) { + NOTREACHED(); + return false; + } + // Add the policy for the pipes. if (policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc index 81b0a74..35a5172 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.cc +++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc @@ -153,10 +153,8 @@ void BrowserGpuChannelHostFactory::EstablishGpuChannelOnIO( void BrowserGpuChannelHostFactory::GpuChannelEstablishedOnIO( EstablishRequest* request, const IPC::ChannelHandle& channel_handle, - base::ProcessHandle gpu_process_handle, const GPUInfo& gpu_info) { request->channel_handle = channel_handle; - request->gpu_process_handle = gpu_process_handle; request->gpu_info = gpu_info; request->event.Signal(); } @@ -191,26 +189,12 @@ GpuChannelHost* BrowserGpuChannelHostFactory::EstablishGpuChannelSync( request.gpu_process_handle == base::kNullProcessHandle) return NULL; - base::ProcessHandle browser_process_for_gpu; -#if defined(OS_WIN) - // Create a process handle that the GPU process can use to access our handles. - DuplicateHandle(base::GetCurrentProcessHandle(), - base::GetCurrentProcessHandle(), - request.gpu_process_handle, - &browser_process_for_gpu, - PROCESS_DUP_HANDLE, - FALSE, - 0); -#else - browser_process_for_gpu = base::GetCurrentProcessHandle(); -#endif - gpu_channel_ = new GpuChannelHost(this, gpu_host_id_, gpu_client_id_); gpu_channel_->set_gpu_info(request.gpu_info); content::GetContentClient()->SetGpuInfo(request.gpu_info); // Connect to the GPU process if a channel name was received. - gpu_channel_->Connect(request.channel_handle, browser_process_for_gpu); + gpu_channel_->Connect(request.channel_handle); return gpu_channel_.get(); } diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h index cfb4e6a..2c58b99 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.h +++ b/content/browser/gpu/browser_gpu_channel_host_factory.h @@ -65,7 +65,6 @@ class BrowserGpuChannelHostFactory : public GpuChannelHostFactory { static void GpuChannelEstablishedOnIO( EstablishRequest* request, const IPC::ChannelHandle& channel_handle, - base::ProcessHandle gpu_process_handle, const GPUInfo& gpu_info); int gpu_client_id_; diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index c4d4e4c..2546131 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc @@ -267,7 +267,6 @@ GpuProcessHost* GpuProcessHost::FromID(int host_id) { GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind) : host_id_(host_id), - gpu_process_(base::kNullProcessHandle), in_process_(false), software_rendering_(false), kind_(kind), @@ -338,11 +337,6 @@ GpuProcessHost::~GpuProcessHost() { content::RESULT_CODE_LAST_CODE); } -#if defined(OS_WIN) - if (gpu_process_) - CloseHandle(gpu_process_); -#endif - // In case we never started, clean up. while (!queued_messages_.empty()) { delete queued_messages_.front(); @@ -498,10 +492,6 @@ void GpuProcessHost::CreateViewCommandBuffer( void GpuProcessHost::OnChannelEstablished( const IPC::ChannelHandle& channel_handle) { - // The GPU process should have launched at this point and this object should - // have been notified of its process handle. - DCHECK(gpu_process_); - EstablishChannelCallback callback = channel_requests_.front(); channel_requests_.pop(); @@ -521,7 +511,7 @@ void GpuProcessHost::OnChannelEstablished( return; } - callback.Run(channel_handle, gpu_process_, + callback.Run(channel_handle, GpuDataManagerImpl::GetInstance()->GetGPUInfo()); } @@ -623,25 +613,6 @@ void GpuProcessHost::OnAcceleratedSurfaceRelease( #endif // OS_WIN && !USE_AURA void GpuProcessHost::OnProcessLaunched() { - // Send the GPU process handle to the UI thread before it has to - // respond to any requests to establish a GPU channel. The response - // to such requests require that the GPU process handle be known. - - base::ProcessHandle child_handle = in_process_ ? - base::GetCurrentProcessHandle() : process_->GetData().handle; - -#if defined(OS_WIN) - DuplicateHandle(base::GetCurrentProcessHandle(), - child_handle, - base::GetCurrentProcessHandle(), - &gpu_process_, - PROCESS_DUP_HANDLE, - FALSE, - 0); -#else - gpu_process_ = child_handle; -#endif - UMA_HISTOGRAM_TIMES("GPU.GPUProcessLaunchTime", base::TimeTicks::Now() - init_start_time_); } @@ -774,7 +745,7 @@ void GpuProcessHost::EstablishChannelError( const IPC::ChannelHandle& channel_handle, base::ProcessHandle renderer_process_for_gpu, const content::GPUInfo& gpu_info) { - callback.Run(channel_handle, renderer_process_for_gpu, gpu_info); + callback.Run(channel_handle, gpu_info); } void GpuProcessHost::CreateCommandBufferError( diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index ae8d98b..f101c6c 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h @@ -41,7 +41,6 @@ class GpuProcessHost : public content::BrowserChildProcessHostDelegate, }; typedef base::Callback<void(const IPC::ChannelHandle&, - base::ProcessHandle, const content::GPUInfo&)> EstablishChannelCallback; @@ -165,9 +164,6 @@ class GpuProcessHost : public content::BrowserChildProcessHostDelegate, // Qeueud messages to send when the process launches. std::queue<IPC::Message*> queued_messages_; - // The handle for the GPU process or null if it is not known to be launched. - base::ProcessHandle gpu_process_; - // Whether we are running a GPU thread inside the browser process instead // of a separate GPU process. bool in_process_; diff --git a/content/browser/renderer_host/gpu_message_filter.cc b/content/browser/renderer_host/gpu_message_filter.cc index d563a91..75ad4fa 100644 --- a/content/browser/renderer_host/gpu_message_filter.cc +++ b/content/browser/renderer_host/gpu_message_filter.cc @@ -173,31 +173,11 @@ void GpuMessageFilter::OnCreateViewCommandBuffer( void GpuMessageFilter::EstablishChannelCallback( IPC::Message* reply, const IPC::ChannelHandle& channel, - base::ProcessHandle gpu_process_for_browser, const content::GPUInfo& gpu_info) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - base::ProcessHandle renderer_process_for_gpu; - if (gpu_process_for_browser != 0) { -#if defined(OS_WIN) - // Create a process handle that the renderer process can give to the GPU - // process to give it access to its handles. - DuplicateHandle(base::GetCurrentProcessHandle(), - peer_handle(), - gpu_process_for_browser, - &renderer_process_for_gpu, - PROCESS_DUP_HANDLE, - FALSE, - 0); -#else - renderer_process_for_gpu = peer_handle(); -#endif - } else { - renderer_process_for_gpu = 0; - } - GpuHostMsg_EstablishGpuChannel::WriteReplyParams( - reply, render_process_id_, channel, renderer_process_for_gpu, gpu_info); + reply, render_process_id_, channel, gpu_info); Send(reply); } diff --git a/content/browser/renderer_host/gpu_message_filter.h b/content/browser/renderer_host/gpu_message_filter.h index aafeeca..e7a73f1 100644 --- a/content/browser/renderer_host/gpu_message_filter.h +++ b/content/browser/renderer_host/gpu_message_filter.h @@ -58,7 +58,6 @@ class GpuMessageFilter : public content::BrowserMessageFilter, // Helper callbacks for the message handlers. void EstablishChannelCallback(IPC::Message* reply, const IPC::ChannelHandle& channel, - base::ProcessHandle gpu_process_for_browser, const content::GPUInfo& gpu_info); void CreateCommandBufferCallback(IPC::Message* reply, int32 route_id); diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc index 1a23eac..1bb1887 100644 --- a/content/common/gpu/client/command_buffer_proxy_impl.cc +++ b/content/common/gpu/client/command_buffer_proxy_impl.cc @@ -20,6 +20,10 @@ #include "gpu/command_buffer/common/command_buffer_shared.h" #include "ui/gfx/size.h" +#if defined(OS_WIN) +#include "content/common/sandbox_policy.h" +#endif + using gpu::Buffer; CommandBufferProxyImpl::CommandBufferProxyImpl( @@ -234,7 +238,13 @@ int32 CommandBufferProxyImpl::CreateTransferBuffer( return -1; base::SharedMemoryHandle handle = shm->handle(); -#if defined(OS_POSIX) +#if defined(OS_WIN) + // Windows needs to explicitly duplicate the handle out to another process. + if (!sandbox::BrokerDuplicateHandle(handle, channel_->gpu_pid(), + &handle, FILE_MAP_WRITE, 0)) { + return -1; + } +#elif defined(OS_POSIX) DCHECK(!handle.auto_close); #endif @@ -257,10 +267,20 @@ int32 CommandBufferProxyImpl::RegisterTransferBuffer( if (last_state_.error != gpu::error::kNoError) return -1; + // Returns FileDescriptor with auto_close off. + base::SharedMemoryHandle handle = shared_memory->handle(); +#if defined(OS_WIN) + // Windows needs to explicitly duplicate the handle out to another process. + if (!sandbox::BrokerDuplicateHandle(handle, channel_->gpu_pid(), + &handle, FILE_MAP_WRITE, 0)) { + return -1; + } +#endif + int32 id; if (!Send(new GpuCommandBufferMsg_RegisterTransferBuffer( route_id_, - shared_memory->handle(), // Returns FileDescriptor with auto_close off. + handle, size, id_request, &id))) { diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc index 988feae..cda0468 100644 --- a/content/common/gpu/client/gpu_channel_host.cc +++ b/content/common/gpu/client/gpu_channel_host.cc @@ -93,10 +93,10 @@ void GpuChannelHost::MessageFilter::OnChannelError() { } GpuChannelHost::GpuChannelHost( - GpuChannelHostFactory* factory, int gpu_process_id, int client_id) + GpuChannelHostFactory* factory, int gpu_host_id, int client_id) : factory_(factory), - gpu_process_id_(gpu_process_id), client_id_(client_id), + gpu_host_id_(gpu_host_id), state_(kUnconnected) { } @@ -104,8 +104,7 @@ GpuChannelHost::~GpuChannelHost() { } void GpuChannelHost::Connect( - const IPC::ChannelHandle& channel_handle, - base::ProcessHandle client_process_for_gpu) { + const IPC::ChannelHandle& channel_handle) { DCHECK(factory_->IsMainThread()); // Open a channel to the GPU process. We pass NULL as the main listener here // since we need to filter everything to route it to the right thread. @@ -130,10 +129,6 @@ void GpuChannelHost::Connect( // and receives the hello message from the GPU process. The messages get // cached. state_ = kConnected; - - // Notify the GPU process of our process handle. This gives it the ability - // to map client handles into the GPU process. - Send(new GpuChannelMsg_Initialize(client_process_for_gpu)); } void GpuChannelHost::set_gpu_info(const content::GPUInfo& gpu_info) { diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h index 0a88845..b82efe9 100644 --- a/content/common/gpu/client/gpu_channel_host.h +++ b/content/common/gpu/client/gpu_channel_host.h @@ -13,6 +13,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" +#include "base/process.h" #include "base/process_util.h" #include "base/synchronization/lock.h" #include "content/common/content_export.h" @@ -83,13 +84,12 @@ class GpuChannelHost : public IPC::Message::Sender, // Called on the render thread GpuChannelHost(GpuChannelHostFactory* factory, - int gpu_process_id, + int gpu_host_id, int client_id); virtual ~GpuChannelHost(); // Connect to GPU process channel. - void Connect(const IPC::ChannelHandle& channel_handle, - base::ProcessHandle client_process_for_gpu); + void Connect(const IPC::ChannelHandle& channel_handle); State state() const { return state_; } @@ -152,7 +152,8 @@ class GpuChannelHost : public IPC::Message::Sender, void ForciblyCloseChannel(); GpuChannelHostFactory* factory() const { return factory_; } - int gpu_process_id() const { return gpu_process_id_; } + int gpu_host_id() const { return gpu_host_id_; } + base::ProcessId gpu_pid() const { return channel_->peer_pid(); } int client_id() const { return client_id_; } private: @@ -180,8 +181,8 @@ class GpuChannelHost : public IPC::Message::Sender, }; GpuChannelHostFactory* factory_; - int gpu_process_id_; int client_id_; + int gpu_host_id_; State state_; diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc index 32e4c2d..aa9c645 100644 --- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc +++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc @@ -484,7 +484,7 @@ void WebGraphicsContext3DCommandBufferImpl::Destroy() { } int WebGraphicsContext3DCommandBufferImpl::GetGPUProcessID() { - return host_ ? host_->gpu_process_id() : 0; + return host_ ? host_->gpu_host_id() : 0; } int WebGraphicsContext3DCommandBufferImpl::GetChannelID() { diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc index 5568b17..96c3553 100644 --- a/content/common/gpu/gpu_channel.cc +++ b/content/common/gpu/gpu_channel.cc @@ -40,8 +40,6 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager, bool software) : gpu_channel_manager_(gpu_channel_manager), client_id_(client_id), - renderer_process_(base::kNullProcessHandle), - renderer_pid_(base::kNullProcessId), share_group_(share_group ? share_group : new gfx::GLShareGroup), watchdog_(watchdog), software_(software), @@ -62,10 +60,6 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager, } GpuChannel::~GpuChannel() { -#if defined(OS_WIN) - if (renderer_process_) - CloseHandle(renderer_process_); -#endif } bool GpuChannel::OnMessageReceived(const IPC::Message& message) { @@ -113,10 +107,6 @@ void GpuChannel::OnChannelError() { gpu_channel_manager_->RemoveChannel(client_id_); } -void GpuChannel::OnChannelConnected(int32 peer_pid) { - renderer_pid_ = peer_pid; -} - bool GpuChannel::Send(IPC::Message* message) { // The GPU process must never send a synchronous IPC message to the renderer // process. This could result in deadlock. @@ -211,7 +201,6 @@ bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) { // here. This is so the reply can be delayed if the scheduler is unscheduled. bool handled = true; IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) - IPC_MESSAGE_HANDLER(GpuChannelMsg_Initialize, OnInitialize) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_CreateOffscreenCommandBuffer, OnCreateOffscreenCommandBuffer) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_DestroyCommandBuffer, @@ -312,15 +301,6 @@ bool GpuChannel::ShouldPreferDiscreteGpu() const { return num_contexts_preferring_discrete_gpu_ > 0; } -void GpuChannel::OnInitialize(base::ProcessHandle renderer_process) { - // Initialize should only happen once. - DCHECK(!renderer_process_); - - // Verify that the renderer has passed its own process handle. - if (base::GetProcId(renderer_process) == renderer_pid_) - renderer_process_ = renderer_process; -} - void GpuChannel::OnCreateOffscreenCommandBuffer( const gfx::Size& size, const GPUCreateCommandBufferConfig& init_params, diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h index a92ed87..d9c5192 100644 --- a/content/common/gpu/gpu_channel.h +++ b/content/common/gpu/gpu_channel.h @@ -62,14 +62,11 @@ class GpuChannel : public IPC::Channel::Listener, int TakeRendererFileDescriptor(); #endif // defined(OS_POSIX) - base::ProcessHandle renderer_process() const { - return renderer_process_; - } + base::ProcessId renderer_pid() const { return channel_->peer_pid(); } // IPC::Channel::Listener implementation: virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; virtual void OnChannelError() OVERRIDE; - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; // IPC::Message::Sender implementation: virtual bool Send(IPC::Message* msg) OVERRIDE; @@ -119,7 +116,6 @@ class GpuChannel : public IPC::Channel::Listener, void ScheduleDelayedWork(GpuCommandBufferStub *stub, int64 delay); // Message handlers. - void OnInitialize(base::ProcessHandle renderer_process); void OnCreateOffscreenCommandBuffer( const gfx::Size& size, const GPUCreateCommandBufferConfig& init_params, @@ -149,12 +145,6 @@ class GpuChannel : public IPC::Channel::Listener, // Uniquely identifies the channel within this GPU process. std::string channel_id_; - // Handle to the renderer process that is on the other side of the channel. - base::ProcessHandle renderer_process_; - - // The process id of the renderer process. - base::ProcessId renderer_pid_; - // Used to implement message routing functionality to CommandBuffer objects MessageRouter router_; diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index 047fb95..1f22bce 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -23,6 +23,10 @@ #include "ui/gfx/gl/gl_bindings.h" #include "ui/gfx/gl/gl_switches.h" +#if defined(OS_WIN) +#include "content/common/sandbox_policy.h" +#endif + GpuCommandBufferStub::SurfaceState::SurfaceState(int32 surface_id, bool visible, base::TimeTicks last_used_time) @@ -467,17 +471,7 @@ void GpuCommandBufferStub::OnRegisterTransferBuffer( size_t size, int32 id_request, IPC::Message* reply_message) { -#if defined(OS_WIN) - // Windows dups the shared memory handle it receives into the current process - // and closes it when this variable goes out of scope. - base::SharedMemory shared_memory(transfer_buffer, - false, - channel_->renderer_process()); -#else - // POSIX receives a dup of the shared memory handle and closes the dup when - // this variable goes out of scope. base::SharedMemory shared_memory(transfer_buffer, false); -#endif if (command_buffer_.get()) { int32 id = command_buffer_->RegisterTransferBuffer(&shared_memory, @@ -506,20 +500,22 @@ void GpuCommandBufferStub::OnDestroyTransferBuffer( void GpuCommandBufferStub::OnGetTransferBuffer( int32 id, IPC::Message* reply_message) { - // Fail if the renderer process has not provided its process handle. - if (!channel_->renderer_process()) - return; - if (command_buffer_.get()) { base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle(); uint32 size = 0; gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id); if (buffer.shared_memory) { - // Assume service is responsible for duplicating the handle to the calling - // process. - buffer.shared_memory->ShareToProcess(channel_->renderer_process(), +#if defined(OS_WIN) + transfer_buffer = NULL; + sandbox::BrokerDuplicateHandle(buffer.shared_memory->handle(), + channel_->renderer_pid(), &transfer_buffer, FILE_MAP_READ | + FILE_MAP_WRITE, 0); + CHECK(transfer_buffer != NULL); +#else + buffer.shared_memory->ShareToProcess(channel_->renderer_pid(), &transfer_buffer); +#endif size = buffer.size; } @@ -557,8 +553,7 @@ void GpuCommandBufferStub::OnCreateVideoDecoder( new GpuVideoDecodeAccelerator(this, decoder_route_id, this); video_decoders_.AddWithID(decoder, decoder_route_id); channel_->AddRoute(decoder_route_id, decoder); - decoder->Initialize(profile, reply_message, - channel_->renderer_process()); + decoder->Initialize(profile, reply_message); } void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) { diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index bd6ce94..d76491a 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -216,11 +216,10 @@ IPC_MESSAGE_CONTROL0(GpuMsg_Hang) // A renderer sends this when it wants to create a connection to the GPU // process. The browser will create the GPU process if necessary, and will // return a handle to the channel via a GpuChannelEstablished message. -IPC_SYNC_MESSAGE_CONTROL1_4(GpuHostMsg_EstablishGpuChannel, +IPC_SYNC_MESSAGE_CONTROL1_3(GpuHostMsg_EstablishGpuChannel, content::CauseForGpuLaunch, int /* client id */, IPC::ChannelHandle /* handle to channel */, - base::ProcessHandle /* renderer_process_for_gpu */, content::GPUInfo /* stats about GPU process*/) // A renderer sends this to the browser process when it wants to @@ -292,13 +291,6 @@ IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceSuspend, // GPU Channel Messages // These are messages from a renderer process to the GPU process. -// Initialize a channel between a renderer process and a GPU process. The -// renderer passes its process handle to the GPU process, which gives gives the -// GPU process the ability to map handles from the renderer process. This must -// be the first message sent on a newly connected channel. -IPC_MESSAGE_CONTROL1(GpuChannelMsg_Initialize, - base::ProcessHandle /* renderer_process_for_gpu */) - // Tells the GPU process to create a new command buffer that renders to an // offscreen frame buffer. IPC_SYNC_MESSAGE_CONTROL2_1(GpuChannelMsg_CreateOffscreenCommandBuffer, diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc index 10f5237..05afbad 100644 --- a/content/common/gpu/media/dxva_video_decode_accelerator.cc +++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc @@ -142,20 +142,9 @@ static IMFSample* CreateInputSample(const uint8* stream, int size, static IMFSample* CreateSampleFromInputBuffer( const media::BitstreamBuffer& bitstream_buffer, - base::ProcessHandle renderer_process, DWORD stream_size, DWORD alignment) { - HANDLE shared_memory_handle = NULL; - RETURN_ON_FAILURE(::DuplicateHandle(renderer_process, - bitstream_buffer.handle(), - base::GetCurrentProcessHandle(), - &shared_memory_handle, - 0, - FALSE, - DUPLICATE_SAME_ACCESS), - "Duplicate handle failed", NULL); - - base::SharedMemory shm(shared_memory_handle, true); + base::SharedMemory shm(bitstream_buffer.handle(), true); RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()), "Failed in base::SharedMemory::Map", NULL); @@ -505,13 +494,11 @@ bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { } DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( - media::VideoDecodeAccelerator::Client* client, - base::ProcessHandle renderer_process) + media::VideoDecodeAccelerator::Client* client) : client_(client), egl_config_(NULL), state_(kUninitialized), pictures_requested_(false), - renderer_process_(renderer_process), last_input_buffer_id_(-1), inputs_before_decode_(0) { memset(&input_stream_info_, 0, sizeof(input_stream_info_)); @@ -560,7 +547,6 @@ void DXVAVideoDecodeAccelerator::Decode( base::win::ScopedComPtr<IMFSample> sample; sample.Attach(CreateSampleFromInputBuffer(bitstream_buffer, - renderer_process_, input_stream_info_.cbSize, input_stream_info_.cbAlignment)); RETURN_AND_NOTIFY_ON_FAILURE(sample, "Failed to create input sample", diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.h b/content/common/gpu/media/dxva_video_decode_accelerator.h index 9c7469e..876ea4b 100644 --- a/content/common/gpu/media/dxva_video_decode_accelerator.h +++ b/content/common/gpu/media/dxva_video_decode_accelerator.h @@ -39,9 +39,8 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator }; // Does not take ownership of |client| which must outlive |*this|. - DXVAVideoDecodeAccelerator( - media::VideoDecodeAccelerator::Client* client, - base::ProcessHandle renderer_process); + explicit DXVAVideoDecodeAccelerator( + media::VideoDecodeAccelerator::Client* client); virtual ~DXVAVideoDecodeAccelerator(); // media::VideoDecodeAccelerator implementation. @@ -187,9 +186,6 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator // Contains the id of the last input buffer received from the client. int32 last_input_buffer_id_; - // Handle to the renderer process. - base::ProcessHandle renderer_process_; - // Ideally the reset token would be a stack variable which is used while // creating the device manager. However it seems that the device manager // holds onto the token and attempts to access it if the underlying device diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc index 224ba3a..0ef9d87 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc @@ -116,8 +116,7 @@ void GpuVideoDecodeAccelerator::NotifyError( void GpuVideoDecodeAccelerator::Initialize( const media::VideoCodecProfile profile, - IPC::Message* init_done_msg, - base::ProcessHandle renderer_process) { + IPC::Message* init_done_msg) { DCHECK(!video_decode_accelerator_.get()); DCHECK(!init_done_msg_); DCHECK(init_done_msg); @@ -133,7 +132,7 @@ void GpuVideoDecodeAccelerator::Initialize( } DLOG(INFO) << "Initializing DXVA HW decoder for windows."; DXVAVideoDecodeAccelerator* video_decoder = - new DXVAVideoDecodeAccelerator(this, renderer_process); + new DXVAVideoDecodeAccelerator(this); #else // OS_WIN OmxVideoDecodeAccelerator* video_decoder = new OmxVideoDecodeAccelerator(this); diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h index 430dda8..2d2e559 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.h +++ b/content/common/gpu/media/gpu_video_decode_accelerator.h @@ -47,8 +47,7 @@ class GpuVideoDecodeAccelerator // The renderer process handle is valid as long as we have a channel between // GPU process and the renderer. void Initialize(const media::VideoCodecProfile profile, - IPC::Message* init_done_msg, - base::ProcessHandle renderer_process); + IPC::Message* init_done_msg); private: diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc index da73e34..9dc6325 100644 --- a/content/common/gpu/media/video_decode_accelerator_unittest.cc +++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc @@ -655,7 +655,7 @@ void EglRenderingVDAClient::CreateDecoder() { CHECK(decoder_deleted()); #if defined(OS_WIN) scoped_refptr<DXVAVideoDecodeAccelerator> decoder = - new DXVAVideoDecodeAccelerator(this, base::GetCurrentProcessHandle()); + new DXVAVideoDecodeAccelerator(this); #else // OS_WIN scoped_refptr<OmxVideoDecodeAccelerator> decoder = new OmxVideoDecodeAccelerator(this); diff --git a/content/common/np_channel_base.h b/content/common/np_channel_base.h index c931949..8bacac3 100644 --- a/content/common/np_channel_base.h +++ b/content/common/np_channel_base.h @@ -12,6 +12,7 @@ #include "base/hash_tables.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/process.h" #include "content/common/message_router.h" #include "content/common/npobject_base.h" #include "ipc/ipc_channel_handle.h" @@ -75,7 +76,7 @@ class NPChannelBase : public IPC::Channel::Listener, // IPC::Message::Sender implementation: virtual bool Send(IPC::Message* msg) OVERRIDE; - int peer_pid() { return peer_pid_; } + base::ProcessId peer_pid() { return channel_->peer_pid(); } IPC::ChannelHandle channel_handle() const { return channel_handle_; } // Returns the number of open NPObject channels in this process. diff --git a/content/common/sandbox_policy.cc b/content/common/sandbox_policy.cc index 11e8602..dc07070 100644 --- a/content/common/sandbox_policy.cc +++ b/content/common/sandbox_policy.cc @@ -374,21 +374,33 @@ bool AddPolicyForGPU(CommandLine* cmd_line, sandbox::TargetPolicy* policy) { if (result != sandbox::SBOX_ALL_OK) return false; + // GPU needs to copy sections to renderers. + result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, + sandbox::TargetPolicy::HANDLES_DUP_ANY, + L"Section"); + if (result != sandbox::SBOX_ALL_OK) + return false; + AddGenericDllEvictionPolicy(policy); #endif return true; } bool AddPolicyForRenderer(sandbox::TargetPolicy* policy) { - // Renderers need to copy sections for plugin DIBs. + // Renderers need to copy sections for plugin DIBs and GPU. sandbox::ResultCode result; result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, sandbox::TargetPolicy::HANDLES_DUP_ANY, L"Section"); - if (result != sandbox::SBOX_ALL_OK) { - NOTREACHED(); + if (result != sandbox::SBOX_ALL_OK) + return false; + + // Renderers need to share events with plugins. + result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, + sandbox::TargetPolicy::HANDLES_DUP_ANY, + L"Event"); + if (result != sandbox::SBOX_ALL_OK) return false; - } policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); @@ -451,30 +463,33 @@ bool BrokerDuplicateHandle(HANDLE source_handle, HANDLE* target_handle, DWORD desired_access, DWORD options) { - // Just use DuplicateHandle() if we aren't in the sandbox. - if (!g_target_services) { - base::win::ScopedHandle target_process(::OpenProcess(PROCESS_DUP_HANDLE, - FALSE, - target_process_id)); - if (!target_process.IsValid()) - return false; - - if (!::DuplicateHandle(::GetCurrentProcess(), source_handle, - target_process, target_handle, - desired_access, FALSE, - options)) { - return false; - } + // If our process is the target just duplicate the handle. + if (::GetCurrentProcessId() == target_process_id) { + return !!::DuplicateHandle(::GetCurrentProcess(), source_handle, + ::GetCurrentProcess(), target_handle, + desired_access, FALSE, options); + } + + // Try the broker next + if (g_target_services && + g_target_services->DuplicateHandle(source_handle, target_process_id, + target_handle, desired_access, + options) == SBOX_ALL_OK) { return true; } - ResultCode result = g_target_services->DuplicateHandle(source_handle, - target_process_id, - target_handle, - desired_access, - options); - return SBOX_ALL_OK == result; + // Finally, see if we already have access to the process. + base::win::ScopedHandle target_process; + target_process.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, + target_process_id)); + if (target_process.IsValid()) { + return !!::DuplicateHandle(::GetCurrentProcess(), source_handle, + target_process, target_handle, + desired_access, FALSE, options); + } + + return false; } @@ -573,6 +588,7 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, policy->Release(); base::ProcessHandle process = 0; base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); + g_broker_services->AddTargetPeer(process); return process; } diff --git a/content/plugin/plugin_channel.cc b/content/plugin/plugin_channel.cc index dd60b67..3f544da 100644 --- a/content/plugin/plugin_channel.cc +++ b/content/plugin/plugin_channel.cc @@ -161,8 +161,7 @@ void PluginChannel::NotifyRenderersOfPendingShutdown() { } PluginChannel::PluginChannel() - : renderer_handle_(0), - renderer_id_(-1), + : renderer_id_(-1), in_send_(0), incognito_(false), filter_(new MessageFilter()) { @@ -173,9 +172,6 @@ PluginChannel::PluginChannel() } PluginChannel::~PluginChannel() { - if (renderer_handle_) - base::CloseProcessHandle(renderer_handle_); - MessageLoop::current()->PostDelayedTask( FROM_HERE, base::Bind(&PluginReleaseCallback), @@ -285,18 +281,7 @@ base::WaitableEvent* PluginChannel::GetModalDialogEvent( return filter_->GetModalDialogEvent(containing_window); } -void PluginChannel::OnChannelConnected(int32 peer_pid) { - base::ProcessHandle handle; - if (!base::OpenProcessHandle(peer_pid, &handle)) { - NOTREACHED(); - } - renderer_handle_ = handle; - NPChannelBase::OnChannelConnected(peer_pid); -} - void PluginChannel::OnChannelError() { - base::CloseProcessHandle(renderer_handle_); - renderer_handle_ = 0; NPChannelBase::OnChannelError(); CleanUp(); } diff --git a/content/plugin/plugin_channel.h b/content/plugin/plugin_channel.h index b83b133..7be4d91 100644 --- a/content/plugin/plugin_channel.h +++ b/content/plugin/plugin_channel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -36,7 +36,6 @@ class PluginChannel : public NPChannelBase { virtual bool Send(IPC::Message* msg) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - base::ProcessHandle renderer_handle() const { return renderer_handle_; } int renderer_id() { return renderer_id_; } virtual int GenerateRouteID() OVERRIDE; @@ -59,7 +58,6 @@ class PluginChannel : public NPChannelBase { protected: // IPC::Channel::Listener implementation: - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; virtual void OnChannelError() OVERRIDE; virtual void CleanUp() OVERRIDE; @@ -88,9 +86,6 @@ class PluginChannel : public NPChannelBase { std::vector<scoped_refptr<WebPluginDelegateStub> > plugin_stubs_; - // Handle to the renderer process who is on the other side of the channel. - base::ProcessHandle renderer_handle_; - // The id of the renderer who is on the other side of the channel. int renderer_id_; diff --git a/content/plugin/webplugin_proxy.cc b/content/plugin/webplugin_proxy.cc index 919f847..704058d 100644 --- a/content/plugin/webplugin_proxy.cc +++ b/content/plugin/webplugin_proxy.cc @@ -35,6 +35,10 @@ #include "ui/base/x/x11_util_internal.h" #endif +#if defined(OS_WIN) +#include "content/common/sandbox_policy.h" +#endif + using WebKit::WebBindings; using webkit::npapi::WebPluginResourceClient; @@ -129,10 +133,9 @@ void WebPluginProxy::WillDestroyWindow(gfx::PluginWindowHandle window) { #if defined(OS_WIN) void WebPluginProxy::SetWindowlessPumpEvent(HANDLE pump_messages_event) { HANDLE pump_messages_event_for_renderer = NULL; - DuplicateHandle(GetCurrentProcess(), pump_messages_event, - channel_->renderer_handle(), - &pump_messages_event_for_renderer, - 0, FALSE, DUPLICATE_SAME_ACCESS); + sandbox::BrokerDuplicateHandle(pump_messages_event, channel_->peer_pid(), + &pump_messages_event_for_renderer, + SYNCHRONIZE | EVENT_MODIFY_STATE, 0); DCHECK(pump_messages_event_for_renderer != NULL); Send(new PluginHostMsg_SetWindowlessPumpEvent( route_id_, pump_messages_event_for_renderer)); @@ -470,25 +473,17 @@ void WebPluginProxy::CreateCanvasFromHandle( const TransportDIB::Handle& dib_handle, const gfx::Rect& window_rect, scoped_ptr<skia::PlatformCanvas>* canvas_out) { - // Create a canvas that will reference the shared bits. We have to handle - // errors here since we're mapping a large amount of memory that may not fit - // in our address space, or go wrong in some other way. - HANDLE section; - DuplicateHandle(channel_->renderer_handle(), dib_handle, GetCurrentProcess(), - §ion, - STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE, - FALSE, 0); scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); if (!canvas->initialize( window_rect.width(), window_rect.height(), true, - section)) { + dib_handle)) { canvas_out->reset(); } canvas_out->reset(canvas.release()); // The canvas does not own the section so we need to close it now. - CloseHandle(section); + CloseHandle(dib_handle); } void WebPluginProxy::SetWindowlessBuffers( diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index a047050..f565201 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc @@ -909,18 +909,15 @@ GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync( // Ask the browser for the channel name. int client_id = 0; IPC::ChannelHandle channel_handle; - base::ProcessHandle renderer_process_for_gpu; content::GPUInfo gpu_info; if (!Send(new GpuHostMsg_EstablishGpuChannel(cause_for_gpu_launch, &client_id, &channel_handle, - &renderer_process_for_gpu, &gpu_info)) || - channel_handle.name.empty() || #if defined(OS_POSIX) channel_handle.socket.fd == -1 || #endif - renderer_process_for_gpu == base::kNullProcessHandle) { + channel_handle.name.empty()) { // Otherwise cancel the connection. gpu_channel_ = NULL; return NULL; @@ -931,7 +928,7 @@ GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync( content::GetContentClient()->SetGpuInfo(gpu_info); // Connect to the GPU process if a channel name was received. - gpu_channel_->Connect(channel_handle, renderer_process_for_gpu); + gpu_channel_->Connect(channel_handle); return GetGpuChannel(); } diff --git a/content/renderer/webplugin_delegate_proxy.cc b/content/renderer/webplugin_delegate_proxy.cc index 5bc6084..b6ff543 100644 --- a/content/renderer/webplugin_delegate_proxy.cc +++ b/content/renderer/webplugin_delegate_proxy.cc @@ -18,6 +18,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/process.h" #include "base/string_split.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" @@ -60,6 +61,10 @@ #include "base/mac/mac_util.h" #endif +#if defined(OS_WIN) +#include "content/common/sandbox_policy.h" +#endif + using WebKit::WebBindings; using WebKit::WebCursorInfo; using WebKit::WebDragData; @@ -484,7 +489,8 @@ void WebPluginDelegateProxy::OnChannelError() { static void CopyTransportDIBHandleForMessage( const TransportDIB::Handle& handle_in, - TransportDIB::Handle* handle_out) { + TransportDIB::Handle* handle_out, + base::ProcessId peer_pid) { #if defined(OS_MACOSX) // On Mac, TransportDIB::Handle is typedef'ed to FileDescriptor, and // FileDescriptor message fields needs to remain valid until the message is @@ -494,6 +500,12 @@ static void CopyTransportDIBHandleForMessage( return; } handle_out->auto_close = true; +#elif defined(OS_WIN) + // On Windows we need to duplicate the handle for the plugin process. + *handle_out = NULL; + sandbox::BrokerDuplicateHandle(handle_in, peer_pid, handle_out, + FILE_MAP_READ | FILE_MAP_WRITE, 0); + CHECK(*handle_out != NULL); #else // Don't need to do anything special for other platforms. *handle_out = handle_in; @@ -520,15 +532,18 @@ void WebPluginDelegateProxy::SendUpdateGeometry( { if (transport_stores_[0].dib.get()) CopyTransportDIBHandleForMessage(transport_stores_[0].dib->handle(), - ¶m.windowless_buffer0); + ¶m.windowless_buffer0, + channel_host_->peer_pid()); if (transport_stores_[1].dib.get()) CopyTransportDIBHandleForMessage(transport_stores_[1].dib->handle(), - ¶m.windowless_buffer1); + ¶m.windowless_buffer1, + channel_host_->peer_pid()); if (background_store_.dib.get()) CopyTransportDIBHandleForMessage(background_store_.dib->handle(), - ¶m.background_buffer); + ¶m.background_buffer, + channel_host_->peer_pid()); } IPC::Message* msg; |