Add security check to getPhysicalDisplayToken binder function.
- There is a possible way to take over the screen display and swap the
display content due to a missing permission check.
- Add a short-term fix for WCG checking failure because of new
permission check added to SF::getPhysicalDisplayToken: change two
function signatures (getStaticDisplayInfo and getDynamicDisplayInfo).
- To make short-term fix workable, split getDynamicDisplayInfo binder
call into two, one is to take display id, one is to take display token
as old codes show to avoid huge modification on other callees.
Bug: 248031255
Test: test using displaytoken app manually on the phone, test shell
screenrecord during using displaytoken; atest
android.hardware.camera2.cts.FastBasicsTest
Change-Id: Id9d9012d4ede9c8330f0ce1096bcb78e51b7c5df
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 36ff3ec..6da6022 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -974,17 +974,14 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::getStaticDisplayInfo(const sp<IBinder>& displayToken,
- ui::StaticDisplayInfo* info) {
- if (!displayToken || !info) {
+status_t SurfaceFlinger::getStaticDisplayInfo(int64_t displayId, ui::StaticDisplayInfo* info) {
+ if (!info) {
return BAD_VALUE;
}
Mutex::Autolock lock(mStateLock);
-
- const auto displayOpt = ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
- .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
- .and_then(getDisplayDeviceAndSnapshot());
+ const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
+ const auto displayOpt = mPhysicalDisplays.get(*id).and_then(getDisplayDeviceAndSnapshot());
if (!displayOpt) {
return NAME_NOT_FOUND;
@@ -1011,26 +1008,10 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::getDynamicDisplayInfo(const sp<IBinder>& displayToken,
- ui::DynamicDisplayInfo* info) {
- if (!displayToken || !info) {
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mStateLock);
-
- const auto displayOpt = ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
- .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
- .and_then(getDisplayDeviceAndSnapshot());
- if (!displayOpt) {
- return NAME_NOT_FOUND;
- }
-
- const auto& [display, snapshotRef] = *displayOpt;
- const auto& snapshot = snapshotRef.get();
-
+void SurfaceFlinger::getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo*& info,
+ const sp<DisplayDevice>& display,
+ const display::DisplaySnapshot& snapshot) {
const auto& displayModes = snapshot.displayModes();
-
info->supportedDisplayModes.clear();
info->supportedDisplayModes.reserve(displayModes.size());
@@ -1104,7 +1085,47 @@
}
}
}
+}
+status_t SurfaceFlinger::getDynamicDisplayInfoFromId(int64_t physicalDisplayId,
+ ui::DynamicDisplayInfo* info) {
+ if (!info) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mStateLock);
+
+ const auto id_ =
+ DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(physicalDisplayId));
+ const auto displayOpt = mPhysicalDisplays.get(*id_).and_then(getDisplayDeviceAndSnapshot());
+
+ if (!displayOpt) {
+ return NAME_NOT_FOUND;
+ }
+
+ const auto& [display, snapshotRef] = *displayOpt;
+ getDynamicDisplayInfoInternal(info, display, snapshotRef.get());
+ return NO_ERROR;
+}
+
+status_t SurfaceFlinger::getDynamicDisplayInfoFromToken(const sp<IBinder>& displayToken,
+ ui::DynamicDisplayInfo* info) {
+ if (!displayToken || !info) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mStateLock);
+
+ const auto displayOpt = ftl::find_if(mPhysicalDisplays, PhysicalDisplay::hasToken(displayToken))
+ .transform(&ftl::to_mapped_ref<PhysicalDisplays>)
+ .and_then(getDisplayDeviceAndSnapshot());
+
+ if (!displayOpt) {
+ return NAME_NOT_FOUND;
+ }
+
+ const auto& [display, snapshotRef] = *displayOpt;
+ getDynamicDisplayInfoInternal(info, display, snapshotRef.get());
return NO_ERROR;
}
@@ -4036,7 +4057,7 @@
bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelineInfo,
std::vector<ResolvedComposerState>& states,
- const Vector<DisplayState>& displays, uint32_t flags,
+ Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
const int64_t desiredPresentTime, bool isAutoTimestamp,
const client_cache_t& uncacheBuffer,
@@ -4045,7 +4066,8 @@
const std::vector<ListenerCallbacks>& listenerCallbacks,
int originPid, int originUid, uint64_t transactionId) {
uint32_t transactionFlags = 0;
- for (const DisplayState& display : displays) {
+ for (DisplayState& display : displays) {
+ display.sanitize(permissions);
transactionFlags |= setDisplayStateLocked(display);
}
@@ -7283,6 +7305,10 @@
binder::Status SurfaceComposerAIDL::getPhysicalDisplayToken(int64_t displayId,
sp<IBinder>* outDisplay) {
+ status_t status = checkAccessPermission();
+ if (status != OK) {
+ return binderStatusFromStatusT(status);
+ }
const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
*outDisplay = mFlinger->getPhysicalDisplayToken(*id);
return binder::Status::ok();
@@ -7333,11 +7359,12 @@
return binderStatusFromStatusT(status);
}
-binder::Status SurfaceComposerAIDL::getStaticDisplayInfo(const sp<IBinder>& display,
+binder::Status SurfaceComposerAIDL::getStaticDisplayInfo(int64_t displayId,
gui::StaticDisplayInfo* outInfo) {
using Tag = gui::DeviceProductInfo::ManufactureOrModelDate::Tag;
ui::StaticDisplayInfo info;
- status_t status = mFlinger->getStaticDisplayInfo(display, &info);
+
+ status_t status = mFlinger->getStaticDisplayInfo(displayId, &info);
if (status == NO_ERROR) {
// convert ui::StaticDisplayInfo to gui::StaticDisplayInfo
outInfo->connectionType = static_cast<gui::DisplayConnectionType>(info.connectionType);
@@ -7376,58 +7403,71 @@
return binderStatusFromStatusT(status);
}
-binder::Status SurfaceComposerAIDL::getDynamicDisplayInfo(const sp<IBinder>& display,
- gui::DynamicDisplayInfo* outInfo) {
+void SurfaceComposerAIDL::getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo& info,
+ gui::DynamicDisplayInfo*& outInfo) {
+ // convert ui::DynamicDisplayInfo to gui::DynamicDisplayInfo
+ outInfo->supportedDisplayModes.clear();
+ outInfo->supportedDisplayModes.reserve(info.supportedDisplayModes.size());
+ for (const auto& mode : info.supportedDisplayModes) {
+ gui::DisplayMode outMode;
+ outMode.id = mode.id;
+ outMode.resolution.width = mode.resolution.width;
+ outMode.resolution.height = mode.resolution.height;
+ outMode.xDpi = mode.xDpi;
+ outMode.yDpi = mode.yDpi;
+ outMode.refreshRate = mode.refreshRate;
+ outMode.appVsyncOffset = mode.appVsyncOffset;
+ outMode.sfVsyncOffset = mode.sfVsyncOffset;
+ outMode.presentationDeadline = mode.presentationDeadline;
+ outMode.group = mode.group;
+ std::transform(mode.supportedHdrTypes.begin(), mode.supportedHdrTypes.end(),
+ std::back_inserter(outMode.supportedHdrTypes),
+ [](const ui::Hdr& value) { return static_cast<int32_t>(value); });
+ outInfo->supportedDisplayModes.push_back(outMode);
+ }
+
+ outInfo->activeDisplayModeId = info.activeDisplayModeId;
+ outInfo->renderFrameRate = info.renderFrameRate;
+
+ outInfo->supportedColorModes.clear();
+ outInfo->supportedColorModes.reserve(info.supportedColorModes.size());
+ for (const auto& cmode : info.supportedColorModes) {
+ outInfo->supportedColorModes.push_back(static_cast<int32_t>(cmode));
+ }
+
+ outInfo->activeColorMode = static_cast<int32_t>(info.activeColorMode);
+
+ gui::HdrCapabilities& hdrCapabilities = outInfo->hdrCapabilities;
+ hdrCapabilities.supportedHdrTypes.clear();
+ hdrCapabilities.supportedHdrTypes.reserve(info.hdrCapabilities.getSupportedHdrTypes().size());
+ for (const auto& hdr : info.hdrCapabilities.getSupportedHdrTypes()) {
+ hdrCapabilities.supportedHdrTypes.push_back(static_cast<int32_t>(hdr));
+ }
+ hdrCapabilities.maxLuminance = info.hdrCapabilities.getDesiredMaxLuminance();
+ hdrCapabilities.maxAverageLuminance = info.hdrCapabilities.getDesiredMaxAverageLuminance();
+ hdrCapabilities.minLuminance = info.hdrCapabilities.getDesiredMinLuminance();
+
+ outInfo->autoLowLatencyModeSupported = info.autoLowLatencyModeSupported;
+ outInfo->gameContentTypeSupported = info.gameContentTypeSupported;
+ outInfo->preferredBootDisplayMode = info.preferredBootDisplayMode;
+}
+
+binder::Status SurfaceComposerAIDL::getDynamicDisplayInfoFromToken(
+ const sp<IBinder>& display, gui::DynamicDisplayInfo* outInfo) {
ui::DynamicDisplayInfo info;
- status_t status = mFlinger->getDynamicDisplayInfo(display, &info);
+ status_t status = mFlinger->getDynamicDisplayInfoFromToken(display, &info);
if (status == NO_ERROR) {
- // convert ui::DynamicDisplayInfo to gui::DynamicDisplayInfo
- outInfo->supportedDisplayModes.clear();
- outInfo->supportedDisplayModes.reserve(info.supportedDisplayModes.size());
- for (const auto& mode : info.supportedDisplayModes) {
- gui::DisplayMode outMode;
- outMode.id = mode.id;
- outMode.resolution.width = mode.resolution.width;
- outMode.resolution.height = mode.resolution.height;
- outMode.xDpi = mode.xDpi;
- outMode.yDpi = mode.yDpi;
- outMode.refreshRate = mode.refreshRate;
- outMode.appVsyncOffset = mode.appVsyncOffset;
- outMode.sfVsyncOffset = mode.sfVsyncOffset;
- outMode.presentationDeadline = mode.presentationDeadline;
- outMode.group = mode.group;
- std::transform(mode.supportedHdrTypes.begin(), mode.supportedHdrTypes.end(),
- std::back_inserter(outMode.supportedHdrTypes),
- [](const ui::Hdr& value) { return static_cast<int32_t>(value); });
+ getDynamicDisplayInfoInternal(info, outInfo);
+ }
+ return binderStatusFromStatusT(status);
+}
- outInfo->supportedDisplayModes.push_back(outMode);
- }
-
- outInfo->activeDisplayModeId = info.activeDisplayModeId;
- outInfo->renderFrameRate = info.renderFrameRate;
-
- outInfo->supportedColorModes.clear();
- outInfo->supportedColorModes.reserve(info.supportedColorModes.size());
- for (const auto& cmode : info.supportedColorModes) {
- outInfo->supportedColorModes.push_back(static_cast<int32_t>(cmode));
- }
-
- outInfo->activeColorMode = static_cast<int32_t>(info.activeColorMode);
-
- gui::HdrCapabilities& hdrCapabilities = outInfo->hdrCapabilities;
- hdrCapabilities.supportedHdrTypes.clear();
- hdrCapabilities.supportedHdrTypes.reserve(
- info.hdrCapabilities.getSupportedHdrTypes().size());
- for (const auto& hdr : info.hdrCapabilities.getSupportedHdrTypes()) {
- hdrCapabilities.supportedHdrTypes.push_back(static_cast<int32_t>(hdr));
- }
- hdrCapabilities.maxLuminance = info.hdrCapabilities.getDesiredMaxLuminance();
- hdrCapabilities.maxAverageLuminance = info.hdrCapabilities.getDesiredMaxAverageLuminance();
- hdrCapabilities.minLuminance = info.hdrCapabilities.getDesiredMinLuminance();
-
- outInfo->autoLowLatencyModeSupported = info.autoLowLatencyModeSupported;
- outInfo->gameContentTypeSupported = info.gameContentTypeSupported;
- outInfo->preferredBootDisplayMode = info.preferredBootDisplayMode;
+binder::Status SurfaceComposerAIDL::getDynamicDisplayInfoFromId(int64_t displayId,
+ gui::DynamicDisplayInfo* outInfo) {
+ ui::DynamicDisplayInfo info;
+ status_t status = mFlinger->getDynamicDisplayInfoFromId(displayId, &info);
+ if (status == NO_ERROR) {
+ getDynamicDisplayInfoInternal(info, outInfo);
}
return binderStatusFromStatusT(status);
}