Commit 6c29bd6c authored by Sam McNally's avatar Sam McNally Committed by Commit Bot

Filter out touchscreen devices with areas that overflow.

When initialized incorrectly, some touchscreen controllers can report
bogus values for their sizes. Chrome uses the touchscreen area in
calculations; if that area overflows a signed 32-bit int, it
check-fails. Thus, a misbehaving touchscreen can cause Chrome to
crash-loop, rendering a device unusable.

Mitigate this by warning about the bogus size and then ignoring the
touchscreen input device. A non-functional touchscreen is better than an
unusable device.

BUG=b:162596241

Change-Id: I9291c176ed778f5ddb8a80d9ea75f17be7bd0554
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2353973Reviewed-by: default avatarMichael Spang <spang@chromium.org>
Commit-Queue: Sam McNally <sammc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798512}
parent 6b89544e
...@@ -107,12 +107,9 @@ std::unique_ptr<EventConverterEvdev> CreateConverter( ...@@ -107,12 +107,9 @@ std::unique_ptr<EventConverterEvdev> CreateConverter(
// Touchscreen: use TouchEventConverterEvdev. // Touchscreen: use TouchEventConverterEvdev.
if (devinfo.HasTouchscreen()) { if (devinfo.HasTouchscreen()) {
std::unique_ptr<TouchEventConverterEvdev> converter( return TouchEventConverterEvdev::Create(
new TouchEventConverterEvdev(std::move(fd), params.path, params.id, std::move(fd), params.path, params.id, devinfo,
devinfo, params.shared_palm_state, params.shared_palm_state, params.dispatcher);
params.dispatcher));
converter->Initialize(devinfo);
return std::move(converter);
} }
// Graphics tablet // Graphics tablet
......
...@@ -138,6 +138,27 @@ TouchEventConverterEvdev::TouchEventConverterEvdev( ...@@ -138,6 +138,27 @@ TouchEventConverterEvdev::TouchEventConverterEvdev(
TouchEventConverterEvdev::~TouchEventConverterEvdev() { TouchEventConverterEvdev::~TouchEventConverterEvdev() {
} }
// static
std::unique_ptr<TouchEventConverterEvdev> TouchEventConverterEvdev::Create(
base::ScopedFD fd,
base::FilePath path,
int id,
const EventDeviceInfo& devinfo,
SharedPalmDetectionFilterState* shared_palm_state,
DeviceEventDispatcherEvdev* dispatcher) {
auto converter = std::make_unique<TouchEventConverterEvdev>(
std::move(fd), std::move(path), id, devinfo, shared_palm_state,
dispatcher);
converter->Initialize(devinfo);
if (!converter->GetTouchscreenSize().GetCheckedArea().IsValid()) {
LOG(WARNING) << "Ignoring touchscreen \"" << converter->input_device().name
<< "\" reporting invalid size "
<< converter->GetTouchscreenSize().ToString();
return nullptr;
}
return converter;
}
void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) { void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
has_mt_ = info.HasMultitouch(); has_mt_ = info.HasMultitouch();
has_pen_ = info.HasKeyEvent(BTN_TOOL_PEN); has_pen_ = info.HasKeyEvent(BTN_TOOL_PEN);
......
...@@ -50,6 +50,14 @@ class COMPONENT_EXPORT(EVDEV) TouchEventConverterEvdev ...@@ -50,6 +50,14 @@ class COMPONENT_EXPORT(EVDEV) TouchEventConverterEvdev
DeviceEventDispatcherEvdev* dispatcher); DeviceEventDispatcherEvdev* dispatcher);
~TouchEventConverterEvdev() override; ~TouchEventConverterEvdev() override;
static std::unique_ptr<TouchEventConverterEvdev> Create(
base::ScopedFD fd,
base::FilePath path,
int id,
const EventDeviceInfo& devinfo,
SharedPalmDetectionFilterState* shared_palm_state,
DeviceEventDispatcherEvdev* dispatcher);
// EventConverterEvdev: // EventConverterEvdev:
bool HasTouchscreen() const override; bool HasTouchscreen() const override;
bool HasPen() const override; bool HasPen() const override;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <vector> #include <vector>
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/files/scoped_file.h" #include "base/files/scoped_file.h"
...@@ -2290,4 +2291,18 @@ TEST_F(TouchEventConverterEvdevTest, FingerSizeWithResolution) { ...@@ -2290,4 +2291,18 @@ TEST_F(TouchEventConverterEvdevTest, FingerSizeWithResolution) {
EXPECT_FLOAT_EQ(14.f, in_progress_event.major); EXPECT_FLOAT_EQ(14.f, in_progress_event.major);
EXPECT_FLOAT_EQ(11.f, in_progress_event.minor); EXPECT_FLOAT_EQ(11.f, in_progress_event.minor);
} }
// b/162596241
TEST_F(TouchEventConverterEvdevTest, InvalidDimensions) {
EventDeviceInfo devinfo;
input_absinfo absinfo = {};
absinfo.maximum = 1 << 16;
devinfo.SetAbsInfo(ABS_X, absinfo);
devinfo.SetAbsInfo(ABS_MT_POSITION_X, absinfo);
devinfo.SetAbsInfo(ABS_Y, absinfo);
devinfo.SetAbsInfo(ABS_MT_POSITION_Y, absinfo);
EXPECT_FALSE(
TouchEventConverterEvdev::Create({}, base::FilePath(kTestDevicePath), 0,
devinfo, shared_palm_state(), nullptr));
}
} // namespace ui } // namespace ui
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment