MidiManagerUsb should not trust indices provided by renderer.
MidiManagerUsb::DispatchSendMidiData takes |port_index| parameter. As it is
provided by a renderer possibly under the control of an attacker, we must
validate the given index before using it.
BUG=456516
Review URL: https://codereview.chromium.org/907793002
Cr-Commit-Position: refs/heads/master@{#315303}
diff --git a/media/midi/midi_manager_usb.cc b/media/midi/midi_manager_usb.cc
index fcefdf5a..63c241b9 100644
--- a/media/midi/midi_manager_usb.cc
+++ b/media/midi/midi_manager_usb.cc
@@ -43,7 +43,13 @@
uint32_t port_index,
const std::vector<uint8>& data,
double timestamp) {
- DCHECK_LT(port_index, output_streams_.size());
+ if (port_index >= output_streams_.size()) {
+ // |port_index| is provided by a renderer so we can't believe that it is
+ // in the valid range.
+ // TODO(toyoshim): Move this check to MidiHost and kill the renderer when
+ // it fails.
+ return;
+ }
output_streams_[port_index]->Send(data);
client->AccumulateMidiBytesSent(data.size());
}
diff --git a/media/midi/midi_manager_usb_unittest.cc b/media/midi/midi_manager_usb_unittest.cc
index 4df64a6..8552403 100644
--- a/media/midi/midi_manager_usb_unittest.cc
+++ b/media/midi/midi_manager_usb_unittest.cc
@@ -316,6 +316,50 @@
logger_.TakeLog());
}
+TEST_F(MidiManagerUsbTest, SendFromCompromizedRenderer) {
+ scoped_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
+ FakeMidiManagerClient client(&logger_);
+ uint8 descriptor[] = {
+ 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
+ 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
+ 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
+ 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
+ 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
+ 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
+ 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
+ 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
+ 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
+ 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
+ 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x25, 0x01, 0x01, 0x07,
+ };
+
+ device->SetDescriptor(ToVector(descriptor));
+ uint8 data[] = {
+ 0x90, 0x45, 0x7f,
+ 0xf0, 0x00, 0x01, 0xf7,
+ };
+
+ Initialize();
+ ScopedVector<UsbMidiDevice> devices;
+ devices.push_back(device.release());
+ EXPECT_FALSE(IsInitializationCallbackInvoked());
+ RunCallbackUntilCallbackInvoked(true, &devices);
+ EXPECT_EQ(MIDI_OK, GetInitializationResult());
+ ASSERT_EQ(2u, manager_->output_streams().size());
+ EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_.TakeLog());
+
+ // The specified port index is invalid. The manager must ignore the request.
+ manager_->DispatchSendMidiData(&client, 99, ToVector(data), 0);
+ EXPECT_EQ("", logger_.TakeLog());
+
+ // The specified port index is invalid. The manager must ignore the request.
+ manager_->DispatchSendMidiData(&client, 2, ToVector(data), 0);
+ EXPECT_EQ("", logger_.TakeLog());
+}
+
TEST_F(MidiManagerUsbTest, Receive) {
scoped_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
uint8 descriptor[] = {