Loading services/surfaceflinger/Layer.cpp +22 −9 Original line number Diff line number Diff line Loading @@ -345,20 +345,25 @@ FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const { win.intersect(s.crop, &win); } Rect bounds = win; const auto& p = mDrawingParent.promote(); FloatRect floatWin = win.toFloatRect(); FloatRect parentBounds = floatWin; if (p != nullptr) { // Look in computeScreenBounds recursive call for explanation of // why we pass false here. bounds = p->computeScreenBounds(false /* reduceTransparentRegion */); // We pass an empty Region here for reasons mirroring that of the case described in // the computeScreenBounds reduceTransparentRegion=false case. parentBounds = p->computeBounds(Region()); } Transform t = getTransform(); Transform t = s.active.transform; FloatRect floatWin = win.toFloatRect(); if (p != nullptr) { if (p != nullptr || !s.finalCrop.isEmpty()) { floatWin = t.transform(floatWin); floatWin = floatWin.intersect(bounds.toFloatRect()); floatWin = floatWin.intersect(parentBounds); if (!s.finalCrop.isEmpty()) { floatWin = floatWin.intersect(s.finalCrop.toFloatRect()); } floatWin = t.inverse().transform(floatWin); } Loading Loading @@ -1249,7 +1254,15 @@ bool Layer::setColor(const half3& color) { return true; } bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix, bool allowNonRectPreservingTransforms) { Transform t; t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); if (!allowNonRectPreservingTransforms && !t.preserveRects()) { ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored"); return false; } mCurrentState.sequence++; mCurrentState.requested.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mCurrentState.modified = true; Loading services/surfaceflinger/Layer.h +1 −1 Original line number Diff line number Diff line Loading @@ -258,7 +258,7 @@ public: // Set a 2x2 transformation matrix on the layer. This transform // will be applied after parent transforms, but before any final // producer specified transform. bool setMatrix(const layer_state_t::matrix22_t& matrix); bool setMatrix(const layer_state_t::matrix22_t& matrix, bool allowNonRectPreservingTransforms); // This second set of geometry attributes are controlled by // setGeometryAppliesWithResize, and their default mode is to be Loading services/surfaceflinger/SurfaceFlinger.cpp +32 −7 Original line number Diff line number Diff line Loading @@ -3342,6 +3342,18 @@ uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) return flags; } bool callingThreadHasUnscopedSurfaceFlingerAccess() { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { return false; } return true; } uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState) { const layer_state_t& s = composerState.state; sp<Client> client(static_cast<Client*>(composerState.client.get())); Loading Loading @@ -3423,7 +3435,22 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState flags |= eTraversalNeeded; } if (what & layer_state_t::eMatrixChanged) { if (layer->setMatrix(s.matrix)) // TODO: b/109894387 // // SurfaceFlinger's renderer is not prepared to handle cropping in the face of arbitrary // rotation. To see the problem observe that if we have a square parent, and a child // of the same size, then we rotate the child 45 degrees around it's center, the child // must now be cropped to a non rectangular 8 sided region. // // Of course we can fix this in the future. For now, we are lucky, SurfaceControl is // private API, and the WindowManager only uses rotation in one case, which is on a top // level layer in which cropping is not an issue. // // However given that abuse of rotation matrices could lead to surfaces extending outside // of cropped areas, we need to prevent non-root clients without permission ACCESS_SURFACE_FLINGER // (a.k.a. everyone except WindowManager and tests) from setting non rectangle preserving // transformations. if (layer->setMatrix(s.matrix, callingThreadHasUnscopedSurfaceFlingerAccess())) flags |= eTraversalNeeded; } if (what & layer_state_t::eTransparentRegionChanged) { Loading Loading @@ -4440,12 +4467,10 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case INJECT_VSYNC: { // codes that require permission check if (!callingThreadHasUnscopedSurfaceFlingerAccess()) { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", ipc->getCallingPid(), ipc->getCallingUid()); return PERMISSION_DENIED; } break; Loading Loading
services/surfaceflinger/Layer.cpp +22 −9 Original line number Diff line number Diff line Loading @@ -345,20 +345,25 @@ FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const { win.intersect(s.crop, &win); } Rect bounds = win; const auto& p = mDrawingParent.promote(); FloatRect floatWin = win.toFloatRect(); FloatRect parentBounds = floatWin; if (p != nullptr) { // Look in computeScreenBounds recursive call for explanation of // why we pass false here. bounds = p->computeScreenBounds(false /* reduceTransparentRegion */); // We pass an empty Region here for reasons mirroring that of the case described in // the computeScreenBounds reduceTransparentRegion=false case. parentBounds = p->computeBounds(Region()); } Transform t = getTransform(); Transform t = s.active.transform; FloatRect floatWin = win.toFloatRect(); if (p != nullptr) { if (p != nullptr || !s.finalCrop.isEmpty()) { floatWin = t.transform(floatWin); floatWin = floatWin.intersect(bounds.toFloatRect()); floatWin = floatWin.intersect(parentBounds); if (!s.finalCrop.isEmpty()) { floatWin = floatWin.intersect(s.finalCrop.toFloatRect()); } floatWin = t.inverse().transform(floatWin); } Loading Loading @@ -1249,7 +1254,15 @@ bool Layer::setColor(const half3& color) { return true; } bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix, bool allowNonRectPreservingTransforms) { Transform t; t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); if (!allowNonRectPreservingTransforms && !t.preserveRects()) { ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored"); return false; } mCurrentState.sequence++; mCurrentState.requested.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mCurrentState.modified = true; Loading
services/surfaceflinger/Layer.h +1 −1 Original line number Diff line number Diff line Loading @@ -258,7 +258,7 @@ public: // Set a 2x2 transformation matrix on the layer. This transform // will be applied after parent transforms, but before any final // producer specified transform. bool setMatrix(const layer_state_t::matrix22_t& matrix); bool setMatrix(const layer_state_t::matrix22_t& matrix, bool allowNonRectPreservingTransforms); // This second set of geometry attributes are controlled by // setGeometryAppliesWithResize, and their default mode is to be Loading
services/surfaceflinger/SurfaceFlinger.cpp +32 −7 Original line number Diff line number Diff line Loading @@ -3342,6 +3342,18 @@ uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) return flags; } bool callingThreadHasUnscopedSurfaceFlingerAccess() { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { return false; } return true; } uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState) { const layer_state_t& s = composerState.state; sp<Client> client(static_cast<Client*>(composerState.client.get())); Loading Loading @@ -3423,7 +3435,22 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState flags |= eTraversalNeeded; } if (what & layer_state_t::eMatrixChanged) { if (layer->setMatrix(s.matrix)) // TODO: b/109894387 // // SurfaceFlinger's renderer is not prepared to handle cropping in the face of arbitrary // rotation. To see the problem observe that if we have a square parent, and a child // of the same size, then we rotate the child 45 degrees around it's center, the child // must now be cropped to a non rectangular 8 sided region. // // Of course we can fix this in the future. For now, we are lucky, SurfaceControl is // private API, and the WindowManager only uses rotation in one case, which is on a top // level layer in which cropping is not an issue. // // However given that abuse of rotation matrices could lead to surfaces extending outside // of cropped areas, we need to prevent non-root clients without permission ACCESS_SURFACE_FLINGER // (a.k.a. everyone except WindowManager and tests) from setting non rectangle preserving // transformations. if (layer->setMatrix(s.matrix, callingThreadHasUnscopedSurfaceFlingerAccess())) flags |= eTraversalNeeded; } if (what & layer_state_t::eTransparentRegionChanged) { Loading Loading @@ -4440,12 +4467,10 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case INJECT_VSYNC: { // codes that require permission check if (!callingThreadHasUnscopedSurfaceFlingerAccess()) { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) && !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", ipc->getCallingPid(), ipc->getCallingUid()); return PERMISSION_DENIED; } break; Loading