### VULNERABILITY DETAILS
The "mojo::WrapSharedMemoryHandle" function is used to produce a "base::SharedBufferHandle" wrapping a given "base::SharedMemoryHandle". The created buffer handle can be sent over Mojo IPC to remote endpoints, including across process boundaries.
In some cases, shared memory descriptors need to be made read-only before being transferred to a different process, in order to ensure that only the owning process can modify the underlying memory. While the "mojo::WrapSharedMemoryHandle" function does provide a flag indicating whether the created buffer handle should be made read-only, this only serves as a hint for the code paths wrapping and unwrapping the handle (specifying how the memory should be mapped), and does not affect the actual properties of the underlying memory region. In particular, calling "mojo::WrapSharedMemoryHandle" with the "read_only" flag set will not result in "SharedMemory::GetReadOnlyHandle" being called on the underlying handle.
Consequently, calling "mojo::WrapSharedMemoryHandle" with the "read_only" flag set is insufficient for producing read-only descriptors for IPC, as the receiving endpoint can remap the received descriptor as writable and modify the shared region's contents. There are a few services which appear to use the aforementioned pattern in order to create "read-only" buffers that can be shared with clients.
For example, the "device::mojom::GamepadMonitor" interface exposed by the "content_browser" service (running in the browser process and exposed to the renderer), allows clients to acquire a "base::SharedBufferHandle" containing the current state of the connected Gamepads. The service attempts to make this memory read-only before passing it to the client, by calling "mojo::WrapSharedMemoryHandle" (https://cs.chromium.org/chromium/src/device/gamepad/gamepad_provider.cc?type=cs&l=95). However, since this does not result in "SharedMemory::GetReadOnlyHandle" being called, the underlying descriptor can be mapped as writable in the receiving process. Other instances of such the same pattern exist in the PDF Compositor client, the Shared Bitmap Allocation Notifier, the Video Encode Accelerator, etc.
I think the issue can be addressed by modifying "mojo::WrapSharedMemoryHandle" to ensure that the underlying memory handle is indeed read-only when a read-only wrapping is requested (or alternately calling GetReadOnlyHandle), thus preventing accidental misuses of the above API.
### VERSION
* Chromium 64.0.3282.0 64-bit
* Revision dd12859a9c856c6919cedf6c35d13b8b22af94e1-refs/heads/master@{#520743}
* OS Linux 4.4.0-97-generic
### REPRODUCTION CASE
I'm attaching a patch that adds code to the renderer process which binds to the "device::mojom::GamepadMonitor" interface and maps the Gamepad memory region as writable. The patch corrupts the memory region to indicate the presence of an active gamepad with a large number of buttons. This will trigger an OOB access by GamepadHasUserGesture (see https://cs.chromium.org/chromium/src/device/gamepad/gamepad_user_gesture.cc?l=27). However, in many cases if another memory region is mapped directly after the gamepad's memory, this will not cause a crash, but will simply set the gamepad as active. For example, on my machine the "Cookies" memory mapping is consistently placed after the gamepad's memory:
```
7fc8cfccd000-7fc8cfcce000 rw-s 00000000 00:18 93 /run/shm/.org.chromium.Chromium.XjyPGf (deleted)
7fc8cfcce000-7fc8cfcdb000 r--s 00000000 fc:02 12481589 /usr/.../chromium/Default/Cookies
```
暂无评论