Loading cmds/installd/InstalldNativeService.cpp +52 −22 Original line number Original line Diff line number Diff line Loading @@ -342,6 +342,56 @@ static int prepare_app_quota(const std::unique_ptr<std::string>& uuid, const std #endif #endif } } static bool prepare_app_profile_dir(const std::string& packageName, int32_t appId, int32_t userId) { if (!property_get_bool("dalvik.vm.usejitprofiles", false)) { return true; } int32_t uid = multiuser_get_uid(userId, appId); int shared_app_gid = multiuser_get_shared_gid(userId, appId); if (shared_app_gid == -1) { // TODO(calin): this should no longer be possible but do not continue if we don't get // a valid shared gid. PLOG(WARNING) << "Invalid shared_app_gid for " << packageName; return true; } const std::string profile_dir = create_primary_current_profile_package_dir_path(userId, packageName); // read-write-execute only for the app user. if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) { PLOG(ERROR) << "Failed to prepare " << profile_dir; return false; } const std::string profile_file = create_current_profile_path(userId, packageName, /*is_secondary_dex*/false); // read-write only for the app user. if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) { PLOG(ERROR) << "Failed to prepare " << profile_file; return false; } const std::string ref_profile_path = create_primary_reference_profile_package_dir_path(packageName); // Prepare the reference profile directory. Note that we use the non strict version of // fs_prepare_dir. This will fix the permission and the ownership to the correct values. // This is particularly important given that in O there were some fixes for how the // shared_app_gid is computed. // // Note that by the time we get here we know that we are using a correct uid (otherwise // prepare_app_dir and the above fs_prepare_file_strict which check the uid). So we // are sure that the gid being used belongs to the owning app and not someone else. // // dex2oat/profman runs under the shared app gid and it needs to read/write reference profiles. if (fs_prepare_dir(ref_profile_path.c_str(), 0770, AID_SYSTEM, shared_app_gid) != 0) { PLOG(ERROR) << "Failed to prepare " << ref_profile_path; return false; } return true; } binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid, binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) { const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) { Loading Loading @@ -417,28 +467,8 @@ binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::s return error("Failed to set hard quota " + path); return error("Failed to set hard quota " + path); } } if (property_get_bool("dalvik.vm.usejitprofiles", false)) { if (!prepare_app_profile_dir(packageName, appId, userId)) { const std::string profile_dir = return error("Failed to prepare profiles for " + packageName); create_primary_current_profile_package_dir_path(userId, pkgname); // read-write-execute only for the app user. if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) { return error("Failed to prepare " + profile_dir); } const std::string profile_file = create_current_profile_path(userId, pkgname, /*is_secondary_dex*/false); // read-write only for the app user. if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) { return error("Failed to prepare " + profile_file); } const std::string ref_profile_path = create_primary_reference_profile_package_dir_path(pkgname); // dex2oat/profman runs under the shared app gid and it needs to read/write reference // profiles. int shared_app_gid = multiuser_get_shared_gid(0, appId); if ((shared_app_gid != -1) && fs_prepare_dir_strict( ref_profile_path.c_str(), 0701, shared_app_gid, shared_app_gid) != 0) { return error("Failed to prepare " + ref_profile_path); } } } } } return ok(); return ok(); Loading cmds/installd/tests/installd_dexopt_test.cpp +58 −5 Original line number Original line Diff line number Diff line Loading @@ -144,10 +144,11 @@ protected: static constexpr uid_t kSystemGid = 1000; static constexpr uid_t kSystemGid = 1000; static constexpr int32_t kOSdkVersion = 25; static constexpr int32_t kOSdkVersion = 25; static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; static constexpr uid_t kTestAppUid = 19999; static constexpr gid_t kTestAppGid = 19999; static constexpr uid_t kTestAppId = kTestAppUid; static constexpr int32_t kTestUserId = 0; static constexpr int32_t kTestUserId = 0; static constexpr uid_t kTestAppId = 19999; const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId); const uid_t kTestAppGid = multiuser_get_shared_gid(kTestUserId, kTestAppId); InstalldNativeService* service_; InstalldNativeService* service_; std::unique_ptr<std::string> volume_uuid_; std::unique_ptr<std::string> volume_uuid_; Loading Loading @@ -245,7 +246,10 @@ protected: void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag, void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag, bool should_binder_call_succeed, bool should_dex_be_compiled = true, bool should_binder_call_succeed, bool should_dex_be_compiled = true, int uid = kTestAppUid) { int32_t uid = -1) { if (uid == -1) { uid = kTestAppUid; } std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_)); std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_)); int32_t dexopt_needed = 0; // does not matter; int32_t dexopt_needed = 0; // does not matter; std::unique_ptr<std::string> out_path = nullptr; // does not matter std::unique_ptr<std::string> out_path = nullptr; // does not matter Loading Loading @@ -279,7 +283,10 @@ protected: void reconcile_secondary_dex(const std::string& path, int32_t storage_flag, void reconcile_secondary_dex(const std::string& path, int32_t storage_flag, bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted, bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted, int uid = kTestAppUid, std::string* package_override = nullptr) { int32_t uid = -1, std::string* package_override = nullptr) { if (uid == -1) { uid = kTestAppUid; } std::vector<std::string> isas; std::vector<std::string> isas; isas.push_back(kRuntimeIsa); isas.push_back(kRuntimeIsa); bool out_secondary_dex_exists = false; bool out_secondary_dex_exists = false; Loading Loading @@ -556,5 +563,51 @@ TEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) { ASSERT_EQ(ENOENT, errno); ASSERT_EQ(ENOENT, errno); } } TEST_F(ProfileTest, ProfileDirOk) { LOG(INFO) << "ProfileDirOk"; std::string cur_profile_dir = create_primary_current_profile_package_dir_path( kTestUserId, package_name_); std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_, /*is_secondary_dex*/false); std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_); CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR); CheckFileAccess(cur_profile_file, kTestAppUid, kTestAppUid, 0600 | S_IFREG); CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR); } // Verify that the profile directories are fixed up during an upgrade. // (The reference profile directory is prepared lazily). TEST_F(ProfileTest, ProfileDirOkAfterFixup) { LOG(INFO) << "ProfileDirOkAfterFixup"; std::string cur_profile_dir = create_primary_current_profile_package_dir_path( kTestUserId, package_name_); std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_, /*is_secondary_dex*/false); std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_); // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700. ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid)); ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700)); // Run createAppData again which will offer to fix-up the profile directories. ASSERT_TRUE(service_->createAppData( volume_uuid_, package_name_, kTestUserId, kAppDataFlags, kTestAppUid, se_info_, kOSdkVersion, &ce_data_inode_).isOk()); // Check the file access. CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR); CheckFileAccess(cur_profile_file, kTestAppUid, kTestAppUid, 0600 | S_IFREG); CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR); } } // namespace installd } // namespace installd } // namespace android } // namespace android libs/gui/ISurfaceComposer.cpp +24 −47 Original line number Original line Diff line number Diff line Loading @@ -100,13 +100,17 @@ public: remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); } } virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer, virtual status_t captureScreen(const sp<IBinder>& display, const sp<IGraphicBufferProducer>& producer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform, int32_t minLayerZ, int32_t maxLayerZ, ISurfaceComposer::Rotation rotation) { bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); data.writeStrongBinder(display); data.writeStrongBinder(IInterface::asBinder(producer)); data.write(sourceCrop); data.write(sourceCrop); data.writeUint32(reqWidth); data.writeUint32(reqWidth); data.writeUint32(reqHeight); data.writeUint32(reqHeight); Loading @@ -114,45 +118,21 @@ public: data.writeInt32(maxLayerZ); data.writeInt32(maxLayerZ); data.writeInt32(static_cast<int32_t>(useIdentityTransform)); data.writeInt32(static_cast<int32_t>(useIdentityTransform)); data.writeInt32(static_cast<int32_t>(rotation)); data.writeInt32(static_cast<int32_t>(rotation)); status_t err = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); return reply.readInt32(); if (err != NO_ERROR) { return err; } err = reply.readInt32(); if (err != NO_ERROR) { return err; } *outBuffer = new GraphicBuffer(); reply.read(**outBuffer); return err; } } virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder, virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop, const sp<IGraphicBufferProducer>& producer, float frameScale) { const Rect& sourceCrop, float frameScale) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(layerHandleBinder); data.writeStrongBinder(layerHandleBinder); data.writeStrongBinder(IInterface::asBinder(producer)); data.write(sourceCrop); data.write(sourceCrop); data.writeFloat(frameScale); data.writeFloat(frameScale); status_t err = remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply); remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply); return reply.readInt32(); if (err != NO_ERROR) { return err; } err = reply.readInt32(); if (err != NO_ERROR) { return err; } *outBuffer = new GraphicBuffer(); reply.read(**outBuffer); return err; } } virtual bool authenticateSurfaceTexture( virtual bool authenticateSurfaceTexture( Loading Loading @@ -603,7 +583,8 @@ status_t BnSurfaceComposer::onTransact( case CAPTURE_SCREEN: { case CAPTURE_SCREEN: { CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> display = data.readStrongBinder(); sp<IBinder> display = data.readStrongBinder(); sp<GraphicBuffer> outBuffer; sp<IGraphicBufferProducer> producer = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); Rect sourceCrop(Rect::EMPTY_RECT); Rect sourceCrop(Rect::EMPTY_RECT); data.read(sourceCrop); data.read(sourceCrop); uint32_t reqWidth = data.readUint32(); uint32_t reqWidth = data.readUint32(); Loading @@ -613,28 +594,24 @@ status_t BnSurfaceComposer::onTransact( bool useIdentityTransform = static_cast<bool>(data.readInt32()); bool useIdentityTransform = static_cast<bool>(data.readInt32()); int32_t rotation = data.readInt32(); int32_t rotation = data.readInt32(); status_t res = captureScreen(display, &outBuffer, sourceCrop, reqWidth, reqHeight, status_t res = captureScreen(display, producer, minLayerZ, maxLayerZ, useIdentityTransform, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, static_cast<ISurfaceComposer::Rotation>(rotation)); static_cast<ISurfaceComposer::Rotation>(rotation)); reply->writeInt32(res); reply->writeInt32(res); if (res == NO_ERROR) { reply->write(*outBuffer); } return NO_ERROR; return NO_ERROR; } } case CAPTURE_LAYERS: { case CAPTURE_LAYERS: { CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> layerHandleBinder = data.readStrongBinder(); sp<IBinder> layerHandleBinder = data.readStrongBinder(); sp<GraphicBuffer> outBuffer; sp<IGraphicBufferProducer> producer = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); Rect sourceCrop(Rect::EMPTY_RECT); Rect sourceCrop(Rect::EMPTY_RECT); data.read(sourceCrop); data.read(sourceCrop); float frameScale = data.readFloat(); float frameScale = data.readFloat(); status_t res = captureLayers(layerHandleBinder, &outBuffer, sourceCrop, frameScale); status_t res = captureLayers(layerHandleBinder, producer, sourceCrop, frameScale); reply->writeInt32(res); reply->writeInt32(res); if (res == NO_ERROR) { reply->write(*outBuffer); } return NO_ERROR; return NO_ERROR; } } case AUTHENTICATE_SURFACE: { case AUTHENTICATE_SURFACE: { Loading libs/gui/Surface.cpp +0 −21 Original line number Original line Diff line number Diff line Loading @@ -1760,25 +1760,4 @@ status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) return OK; return OK; } } status_t Surface::attachAndQueueBuffer(Surface* surface, sp<GraphicBuffer> buffer) { if (buffer == nullptr) { return BAD_VALUE; } int err = static_cast<ANativeWindow*>(surface)->perform(surface, NATIVE_WINDOW_API_CONNECT, NATIVE_WINDOW_API_CPU); if (err != OK) { return err; } err = surface->attachBuffer(buffer->getNativeBuffer()); if (err != OK) { return err; } err = static_cast<ANativeWindow*>(surface)->queueBuffer(surface, buffer->getNativeBuffer(), -1); if (err != OK) { return err; } err = surface->disconnect(NATIVE_WINDOW_API_CPU); return err; } }; // namespace android }; // namespace android libs/gui/SurfaceComposerClient.cpp +164 −10 Original line number Original line Diff line number Diff line Loading @@ -717,27 +717,181 @@ status_t SurfaceComposerClient::getHdrCapabilities(const sp<IBinder>& display, // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, status_t ScreenshotClient::capture( uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, const sp<IBinder>& display, bool useIdentityTransform, uint32_t rotation, const sp<IGraphicBufferProducer>& producer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; return s->captureScreen(display, producer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform); } status_t ScreenshotClient::captureToBuffer(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform, uint32_t rotation, sp<GraphicBuffer>* outBuffer) { sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; if (s == NULL) return NO_INIT; status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, sp<IGraphicBufferConsumer> gbpConsumer; sp<IGraphicBufferProducer> producer; BufferQueue::createBufferQueue(&producer, &gbpConsumer); sp<BufferItemConsumer> consumer(new BufferItemConsumer(gbpConsumer, GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_NEVER, 1, true)); status_t ret = s->captureScreen(display, producer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, static_cast<ISurfaceComposer::Rotation>(rotation)); static_cast<ISurfaceComposer::Rotation>(rotation)); if (ret != NO_ERROR) { if (ret != NO_ERROR) { return ret; return ret; } } BufferItem b; consumer->acquireBuffer(&b, 0, true); *outBuffer = b.mGraphicBuffer; return ret; return ret; } } status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, const sp<IGraphicBufferProducer>& producer, Rect sourceCrop, float frameScale) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; return s->captureLayers(layerHandle, producer, sourceCrop, frameScale); } status_t ScreenshotClient::captureLayersToBuffer(const sp<IBinder>& layerHandle, Rect sourceCrop, float frameScale, sp<GraphicBuffer>* outBuffer) { float frameScale, sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; if (s == NULL) return NO_INIT; status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale); sp<IGraphicBufferConsumer> gbpConsumer; sp<IGraphicBufferProducer> producer; BufferQueue::createBufferQueue(&producer, &gbpConsumer); sp<BufferItemConsumer> consumer(new BufferItemConsumer(gbpConsumer, GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_NEVER, 1, true)); status_t ret = s->captureLayers(layerHandle, producer, sourceCrop, frameScale); if (ret != NO_ERROR) { return ret; } BufferItem b; consumer->acquireBuffer(&b, 0, true); *outBuffer = b.mGraphicBuffer; return ret; return ret; } } ScreenshotClient::ScreenshotClient() : mHaveBuffer(false) { memset(&mBuffer, 0, sizeof(mBuffer)); } ScreenshotClient::~ScreenshotClient() { ScreenshotClient::release(); } sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const { if (mCpuConsumer == NULL) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&mProducer, &consumer); mCpuConsumer = new CpuConsumer(consumer, 1); mCpuConsumer->setName(String8("ScreenshotClient")); } return mCpuConsumer; } status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform, uint32_t rotation) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; sp<CpuConsumer> cpuConsumer = getCpuConsumer(); if (mHaveBuffer) { mCpuConsumer->unlockBuffer(mBuffer); memset(&mBuffer, 0, sizeof(mBuffer)); mHaveBuffer = false; } status_t err = s->captureScreen(display, mProducer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, static_cast<ISurfaceComposer::Rotation>(rotation)); if (err == NO_ERROR) { err = mCpuConsumer->lockNextBuffer(&mBuffer); if (err == NO_ERROR) { mHaveBuffer = true; } } return err; } status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform) { return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, ISurfaceComposer::eRotateNone); } status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, bool useIdentityTransform) { return ScreenshotClient::update(display, sourceCrop, 0, 0, INT32_MIN, INT32_MAX, useIdentityTransform, ISurfaceComposer::eRotateNone); } status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) { return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight, INT32_MIN, INT32_MAX, useIdentityTransform, ISurfaceComposer::eRotateNone); } void ScreenshotClient::release() { if (mHaveBuffer) { mCpuConsumer->unlockBuffer(mBuffer); memset(&mBuffer, 0, sizeof(mBuffer)); mHaveBuffer = false; } mCpuConsumer.clear(); } void const* ScreenshotClient::getPixels() const { return mBuffer.data; } uint32_t ScreenshotClient::getWidth() const { return mBuffer.width; } uint32_t ScreenshotClient::getHeight() const { return mBuffer.height; } PixelFormat ScreenshotClient::getFormat() const { return mBuffer.format; } uint32_t ScreenshotClient::getStride() const { return mBuffer.stride; } size_t ScreenshotClient::getSize() const { return mBuffer.stride * mBuffer.height * bytesPerPixel(mBuffer.format); } android_dataspace ScreenshotClient::getDataSpace() const { return mBuffer.dataSpace; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- }; // namespace android }; // namespace android Loading
cmds/installd/InstalldNativeService.cpp +52 −22 Original line number Original line Diff line number Diff line Loading @@ -342,6 +342,56 @@ static int prepare_app_quota(const std::unique_ptr<std::string>& uuid, const std #endif #endif } } static bool prepare_app_profile_dir(const std::string& packageName, int32_t appId, int32_t userId) { if (!property_get_bool("dalvik.vm.usejitprofiles", false)) { return true; } int32_t uid = multiuser_get_uid(userId, appId); int shared_app_gid = multiuser_get_shared_gid(userId, appId); if (shared_app_gid == -1) { // TODO(calin): this should no longer be possible but do not continue if we don't get // a valid shared gid. PLOG(WARNING) << "Invalid shared_app_gid for " << packageName; return true; } const std::string profile_dir = create_primary_current_profile_package_dir_path(userId, packageName); // read-write-execute only for the app user. if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) { PLOG(ERROR) << "Failed to prepare " << profile_dir; return false; } const std::string profile_file = create_current_profile_path(userId, packageName, /*is_secondary_dex*/false); // read-write only for the app user. if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) { PLOG(ERROR) << "Failed to prepare " << profile_file; return false; } const std::string ref_profile_path = create_primary_reference_profile_package_dir_path(packageName); // Prepare the reference profile directory. Note that we use the non strict version of // fs_prepare_dir. This will fix the permission and the ownership to the correct values. // This is particularly important given that in O there were some fixes for how the // shared_app_gid is computed. // // Note that by the time we get here we know that we are using a correct uid (otherwise // prepare_app_dir and the above fs_prepare_file_strict which check the uid). So we // are sure that the gid being used belongs to the owning app and not someone else. // // dex2oat/profman runs under the shared app gid and it needs to read/write reference profiles. if (fs_prepare_dir(ref_profile_path.c_str(), 0770, AID_SYSTEM, shared_app_gid) != 0) { PLOG(ERROR) << "Failed to prepare " << ref_profile_path; return false; } return true; } binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid, binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) { const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) { Loading Loading @@ -417,28 +467,8 @@ binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::s return error("Failed to set hard quota " + path); return error("Failed to set hard quota " + path); } } if (property_get_bool("dalvik.vm.usejitprofiles", false)) { if (!prepare_app_profile_dir(packageName, appId, userId)) { const std::string profile_dir = return error("Failed to prepare profiles for " + packageName); create_primary_current_profile_package_dir_path(userId, pkgname); // read-write-execute only for the app user. if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) { return error("Failed to prepare " + profile_dir); } const std::string profile_file = create_current_profile_path(userId, pkgname, /*is_secondary_dex*/false); // read-write only for the app user. if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) { return error("Failed to prepare " + profile_file); } const std::string ref_profile_path = create_primary_reference_profile_package_dir_path(pkgname); // dex2oat/profman runs under the shared app gid and it needs to read/write reference // profiles. int shared_app_gid = multiuser_get_shared_gid(0, appId); if ((shared_app_gid != -1) && fs_prepare_dir_strict( ref_profile_path.c_str(), 0701, shared_app_gid, shared_app_gid) != 0) { return error("Failed to prepare " + ref_profile_path); } } } } } return ok(); return ok(); Loading
cmds/installd/tests/installd_dexopt_test.cpp +58 −5 Original line number Original line Diff line number Diff line Loading @@ -144,10 +144,11 @@ protected: static constexpr uid_t kSystemGid = 1000; static constexpr uid_t kSystemGid = 1000; static constexpr int32_t kOSdkVersion = 25; static constexpr int32_t kOSdkVersion = 25; static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; static constexpr uid_t kTestAppUid = 19999; static constexpr gid_t kTestAppGid = 19999; static constexpr uid_t kTestAppId = kTestAppUid; static constexpr int32_t kTestUserId = 0; static constexpr int32_t kTestUserId = 0; static constexpr uid_t kTestAppId = 19999; const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId); const uid_t kTestAppGid = multiuser_get_shared_gid(kTestUserId, kTestAppId); InstalldNativeService* service_; InstalldNativeService* service_; std::unique_ptr<std::string> volume_uuid_; std::unique_ptr<std::string> volume_uuid_; Loading Loading @@ -245,7 +246,10 @@ protected: void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag, void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag, bool should_binder_call_succeed, bool should_dex_be_compiled = true, bool should_binder_call_succeed, bool should_dex_be_compiled = true, int uid = kTestAppUid) { int32_t uid = -1) { if (uid == -1) { uid = kTestAppUid; } std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_)); std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_)); int32_t dexopt_needed = 0; // does not matter; int32_t dexopt_needed = 0; // does not matter; std::unique_ptr<std::string> out_path = nullptr; // does not matter std::unique_ptr<std::string> out_path = nullptr; // does not matter Loading Loading @@ -279,7 +283,10 @@ protected: void reconcile_secondary_dex(const std::string& path, int32_t storage_flag, void reconcile_secondary_dex(const std::string& path, int32_t storage_flag, bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted, bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted, int uid = kTestAppUid, std::string* package_override = nullptr) { int32_t uid = -1, std::string* package_override = nullptr) { if (uid == -1) { uid = kTestAppUid; } std::vector<std::string> isas; std::vector<std::string> isas; isas.push_back(kRuntimeIsa); isas.push_back(kRuntimeIsa); bool out_secondary_dex_exists = false; bool out_secondary_dex_exists = false; Loading Loading @@ -556,5 +563,51 @@ TEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) { ASSERT_EQ(ENOENT, errno); ASSERT_EQ(ENOENT, errno); } } TEST_F(ProfileTest, ProfileDirOk) { LOG(INFO) << "ProfileDirOk"; std::string cur_profile_dir = create_primary_current_profile_package_dir_path( kTestUserId, package_name_); std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_, /*is_secondary_dex*/false); std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_); CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR); CheckFileAccess(cur_profile_file, kTestAppUid, kTestAppUid, 0600 | S_IFREG); CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR); } // Verify that the profile directories are fixed up during an upgrade. // (The reference profile directory is prepared lazily). TEST_F(ProfileTest, ProfileDirOkAfterFixup) { LOG(INFO) << "ProfileDirOkAfterFixup"; std::string cur_profile_dir = create_primary_current_profile_package_dir_path( kTestUserId, package_name_); std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_, /*is_secondary_dex*/false); std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_); // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700. ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid)); ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700)); // Run createAppData again which will offer to fix-up the profile directories. ASSERT_TRUE(service_->createAppData( volume_uuid_, package_name_, kTestUserId, kAppDataFlags, kTestAppUid, se_info_, kOSdkVersion, &ce_data_inode_).isOk()); // Check the file access. CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR); CheckFileAccess(cur_profile_file, kTestAppUid, kTestAppUid, 0600 | S_IFREG); CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR); } } // namespace installd } // namespace installd } // namespace android } // namespace android
libs/gui/ISurfaceComposer.cpp +24 −47 Original line number Original line Diff line number Diff line Loading @@ -100,13 +100,17 @@ public: remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); } } virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer, virtual status_t captureScreen(const sp<IBinder>& display, const sp<IGraphicBufferProducer>& producer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform, int32_t minLayerZ, int32_t maxLayerZ, ISurfaceComposer::Rotation rotation) { bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); data.writeStrongBinder(display); data.writeStrongBinder(IInterface::asBinder(producer)); data.write(sourceCrop); data.write(sourceCrop); data.writeUint32(reqWidth); data.writeUint32(reqWidth); data.writeUint32(reqHeight); data.writeUint32(reqHeight); Loading @@ -114,45 +118,21 @@ public: data.writeInt32(maxLayerZ); data.writeInt32(maxLayerZ); data.writeInt32(static_cast<int32_t>(useIdentityTransform)); data.writeInt32(static_cast<int32_t>(useIdentityTransform)); data.writeInt32(static_cast<int32_t>(rotation)); data.writeInt32(static_cast<int32_t>(rotation)); status_t err = remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); return reply.readInt32(); if (err != NO_ERROR) { return err; } err = reply.readInt32(); if (err != NO_ERROR) { return err; } *outBuffer = new GraphicBuffer(); reply.read(**outBuffer); return err; } } virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder, virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop, const sp<IGraphicBufferProducer>& producer, float frameScale) { const Rect& sourceCrop, float frameScale) { Parcel data, reply; Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(layerHandleBinder); data.writeStrongBinder(layerHandleBinder); data.writeStrongBinder(IInterface::asBinder(producer)); data.write(sourceCrop); data.write(sourceCrop); data.writeFloat(frameScale); data.writeFloat(frameScale); status_t err = remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply); remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply); return reply.readInt32(); if (err != NO_ERROR) { return err; } err = reply.readInt32(); if (err != NO_ERROR) { return err; } *outBuffer = new GraphicBuffer(); reply.read(**outBuffer); return err; } } virtual bool authenticateSurfaceTexture( virtual bool authenticateSurfaceTexture( Loading Loading @@ -603,7 +583,8 @@ status_t BnSurfaceComposer::onTransact( case CAPTURE_SCREEN: { case CAPTURE_SCREEN: { CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> display = data.readStrongBinder(); sp<IBinder> display = data.readStrongBinder(); sp<GraphicBuffer> outBuffer; sp<IGraphicBufferProducer> producer = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); Rect sourceCrop(Rect::EMPTY_RECT); Rect sourceCrop(Rect::EMPTY_RECT); data.read(sourceCrop); data.read(sourceCrop); uint32_t reqWidth = data.readUint32(); uint32_t reqWidth = data.readUint32(); Loading @@ -613,28 +594,24 @@ status_t BnSurfaceComposer::onTransact( bool useIdentityTransform = static_cast<bool>(data.readInt32()); bool useIdentityTransform = static_cast<bool>(data.readInt32()); int32_t rotation = data.readInt32(); int32_t rotation = data.readInt32(); status_t res = captureScreen(display, &outBuffer, sourceCrop, reqWidth, reqHeight, status_t res = captureScreen(display, producer, minLayerZ, maxLayerZ, useIdentityTransform, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, static_cast<ISurfaceComposer::Rotation>(rotation)); static_cast<ISurfaceComposer::Rotation>(rotation)); reply->writeInt32(res); reply->writeInt32(res); if (res == NO_ERROR) { reply->write(*outBuffer); } return NO_ERROR; return NO_ERROR; } } case CAPTURE_LAYERS: { case CAPTURE_LAYERS: { CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> layerHandleBinder = data.readStrongBinder(); sp<IBinder> layerHandleBinder = data.readStrongBinder(); sp<GraphicBuffer> outBuffer; sp<IGraphicBufferProducer> producer = interface_cast<IGraphicBufferProducer>(data.readStrongBinder()); Rect sourceCrop(Rect::EMPTY_RECT); Rect sourceCrop(Rect::EMPTY_RECT); data.read(sourceCrop); data.read(sourceCrop); float frameScale = data.readFloat(); float frameScale = data.readFloat(); status_t res = captureLayers(layerHandleBinder, &outBuffer, sourceCrop, frameScale); status_t res = captureLayers(layerHandleBinder, producer, sourceCrop, frameScale); reply->writeInt32(res); reply->writeInt32(res); if (res == NO_ERROR) { reply->write(*outBuffer); } return NO_ERROR; return NO_ERROR; } } case AUTHENTICATE_SURFACE: { case AUTHENTICATE_SURFACE: { Loading
libs/gui/Surface.cpp +0 −21 Original line number Original line Diff line number Diff line Loading @@ -1760,25 +1760,4 @@ status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) return OK; return OK; } } status_t Surface::attachAndQueueBuffer(Surface* surface, sp<GraphicBuffer> buffer) { if (buffer == nullptr) { return BAD_VALUE; } int err = static_cast<ANativeWindow*>(surface)->perform(surface, NATIVE_WINDOW_API_CONNECT, NATIVE_WINDOW_API_CPU); if (err != OK) { return err; } err = surface->attachBuffer(buffer->getNativeBuffer()); if (err != OK) { return err; } err = static_cast<ANativeWindow*>(surface)->queueBuffer(surface, buffer->getNativeBuffer(), -1); if (err != OK) { return err; } err = surface->disconnect(NATIVE_WINDOW_API_CPU); return err; } }; // namespace android }; // namespace android
libs/gui/SurfaceComposerClient.cpp +164 −10 Original line number Original line Diff line number Diff line Loading @@ -717,27 +717,181 @@ status_t SurfaceComposerClient::getHdrCapabilities(const sp<IBinder>& display, // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, status_t ScreenshotClient::capture( uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, const sp<IBinder>& display, bool useIdentityTransform, uint32_t rotation, const sp<IGraphicBufferProducer>& producer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; return s->captureScreen(display, producer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform); } status_t ScreenshotClient::captureToBuffer(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform, uint32_t rotation, sp<GraphicBuffer>* outBuffer) { sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; if (s == NULL) return NO_INIT; status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, sp<IGraphicBufferConsumer> gbpConsumer; sp<IGraphicBufferProducer> producer; BufferQueue::createBufferQueue(&producer, &gbpConsumer); sp<BufferItemConsumer> consumer(new BufferItemConsumer(gbpConsumer, GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_NEVER, 1, true)); status_t ret = s->captureScreen(display, producer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, static_cast<ISurfaceComposer::Rotation>(rotation)); static_cast<ISurfaceComposer::Rotation>(rotation)); if (ret != NO_ERROR) { if (ret != NO_ERROR) { return ret; return ret; } } BufferItem b; consumer->acquireBuffer(&b, 0, true); *outBuffer = b.mGraphicBuffer; return ret; return ret; } } status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, const sp<IGraphicBufferProducer>& producer, Rect sourceCrop, float frameScale) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; return s->captureLayers(layerHandle, producer, sourceCrop, frameScale); } status_t ScreenshotClient::captureLayersToBuffer(const sp<IBinder>& layerHandle, Rect sourceCrop, float frameScale, sp<GraphicBuffer>* outBuffer) { float frameScale, sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; if (s == NULL) return NO_INIT; status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale); sp<IGraphicBufferConsumer> gbpConsumer; sp<IGraphicBufferProducer> producer; BufferQueue::createBufferQueue(&producer, &gbpConsumer); sp<BufferItemConsumer> consumer(new BufferItemConsumer(gbpConsumer, GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_NEVER, 1, true)); status_t ret = s->captureLayers(layerHandle, producer, sourceCrop, frameScale); if (ret != NO_ERROR) { return ret; } BufferItem b; consumer->acquireBuffer(&b, 0, true); *outBuffer = b.mGraphicBuffer; return ret; return ret; } } ScreenshotClient::ScreenshotClient() : mHaveBuffer(false) { memset(&mBuffer, 0, sizeof(mBuffer)); } ScreenshotClient::~ScreenshotClient() { ScreenshotClient::release(); } sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const { if (mCpuConsumer == NULL) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&mProducer, &consumer); mCpuConsumer = new CpuConsumer(consumer, 1); mCpuConsumer->setName(String8("ScreenshotClient")); } return mCpuConsumer; } status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform, uint32_t rotation) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; sp<CpuConsumer> cpuConsumer = getCpuConsumer(); if (mHaveBuffer) { mCpuConsumer->unlockBuffer(mBuffer); memset(&mBuffer, 0, sizeof(mBuffer)); mHaveBuffer = false; } status_t err = s->captureScreen(display, mProducer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, static_cast<ISurfaceComposer::Rotation>(rotation)); if (err == NO_ERROR) { err = mCpuConsumer->lockNextBuffer(&mBuffer); if (err == NO_ERROR) { mHaveBuffer = true; } } return err; } status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, bool useIdentityTransform) { return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, ISurfaceComposer::eRotateNone); } status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, bool useIdentityTransform) { return ScreenshotClient::update(display, sourceCrop, 0, 0, INT32_MIN, INT32_MAX, useIdentityTransform, ISurfaceComposer::eRotateNone); } status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) { return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight, INT32_MIN, INT32_MAX, useIdentityTransform, ISurfaceComposer::eRotateNone); } void ScreenshotClient::release() { if (mHaveBuffer) { mCpuConsumer->unlockBuffer(mBuffer); memset(&mBuffer, 0, sizeof(mBuffer)); mHaveBuffer = false; } mCpuConsumer.clear(); } void const* ScreenshotClient::getPixels() const { return mBuffer.data; } uint32_t ScreenshotClient::getWidth() const { return mBuffer.width; } uint32_t ScreenshotClient::getHeight() const { return mBuffer.height; } PixelFormat ScreenshotClient::getFormat() const { return mBuffer.format; } uint32_t ScreenshotClient::getStride() const { return mBuffer.stride; } size_t ScreenshotClient::getSize() const { return mBuffer.stride * mBuffer.height * bytesPerPixel(mBuffer.format); } android_dataspace ScreenshotClient::getDataSpace() const { return mBuffer.dataSpace; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- }; // namespace android }; // namespace android