Merge "Fix NPE on a device having no sensor" into pi-dev
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index e53a223..833ffbf 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -22,6 +22,7 @@
#include <errno.h>
#include <fstream>
#include <fts.h>
+#include <functional>
#include <inttypes.h>
#include <regex>
#include <stdlib.h>
@@ -2412,27 +2413,25 @@
// This kernel feature is experimental.
// TODO: remove local definition once upstreamed
-#ifndef FS_IOC_SET_FSVERITY
-struct fsverity_set {
- __u64 offset;
- __u64 flags;
+#ifndef FS_IOC_ENABLE_VERITY
+
+#define FS_IOC_ENABLE_VERITY _IO('f', 133)
+#define FS_IOC_SET_VERITY_MEASUREMENT _IOW('f', 134, struct fsverity_measurement)
+
+#define FS_VERITY_ALG_SHA256 1
+
+struct fsverity_measurement {
+ __u16 digest_algorithm;
+ __u16 digest_size;
+ __u32 reserved1;
+ __u64 reserved2[3];
+ __u8 digest[];
};
-struct fsverity_root_hash {
- short root_hash_algorithm;
- short flags;
- __u8 reserved[4];
- __u8 root_hash[64];
-};
-
-#define FS_IOC_MEASURE_FSVERITY _IOW('f', 133, struct fsverity_root_hash)
-#define FS_IOC_SET_FSVERITY _IOW('f', 134, struct fsverity_set)
-
-#define FSVERITY_FLAG_ENABLED 0x0001
#endif
binder::Status InstalldNativeService::installApkVerity(const std::string& filePath,
- const ::android::base::unique_fd& verityInputAshmem) {
+ const ::android::base::unique_fd& verityInputAshmem, int32_t contentSize) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(filePath);
std::lock_guard<std::recursive_mutex> lock(mLock);
@@ -2440,7 +2439,7 @@
if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) {
return ok();
}
-#if DEBUG
+#ifndef NDEBUG
ASSERT_PAGE_SIZE_4K();
#endif
// TODO: also check fsverity support in the current file system if compiled with DEBUG.
@@ -2449,15 +2448,14 @@
return error("FD is not an ashmem");
}
- // TODO(71871109): Validate filePath.
// 1. Seek to the next page boundary beyond the end of the file.
::android::base::unique_fd wfd(open(filePath.c_str(), O_WRONLY));
if (wfd.get() < 0) {
- return error("Failed to open " + filePath + ": " + strerror(errno));
+ return error("Failed to open " + filePath);
}
struct stat st;
if (fstat(wfd.get(), &st) < 0) {
- return error("Failed to stat " + filePath + ": " + strerror(errno));
+ return error("Failed to stat " + filePath);
}
// fsverity starts from the block boundary.
off_t padding = kVerityPageSize - st.st_size % kVerityPageSize;
@@ -2465,38 +2463,51 @@
padding = 0;
}
if (lseek(wfd.get(), st.st_size + padding, SEEK_SET) < 0) {
- return error("Failed to lseek " + filePath + ": " + strerror(errno));
+ return error("Failed to lseek " + filePath);
}
- // 2. Write everything in the ashmem to the file.
- int size = ashmem_get_size_region(verityInputAshmem.get());
- if (size < 0) {
- return error("Failed to get ashmem size: " + std::to_string(size));
+ // 2. Write everything in the ashmem to the file. Note that allocated
+ // ashmem size is multiple of page size, which is different from the
+ // actual content size.
+ int shmSize = ashmem_get_size_region(verityInputAshmem.get());
+ if (shmSize < 0) {
+ return error("Failed to get ashmem size: " + std::to_string(shmSize));
}
- void* data = mmap(NULL, size, PROT_READ, MAP_SHARED, verityInputAshmem.get(), 0);
- if (data == MAP_FAILED) {
- return error("Failed to mmap the ashmem: " + std::string(strerror(errno)));
+ if (contentSize < 0) {
+ return error("Invalid content size: " + std::to_string(contentSize));
}
- char* cursor = reinterpret_cast<char*>(data);
- int remaining = size;
+ if (contentSize > shmSize) {
+ return error("Content size overflow: " + std::to_string(contentSize) + " > " +
+ std::to_string(shmSize));
+ }
+ auto data = std::unique_ptr<void, std::function<void (void *)>>(
+ mmap(NULL, contentSize, PROT_READ, MAP_SHARED, verityInputAshmem.get(), 0),
+ [contentSize] (void* ptr) {
+ if (ptr != MAP_FAILED) {
+ munmap(ptr, contentSize);
+ }
+ });
+
+ if (data.get() == MAP_FAILED) {
+ return error("Failed to mmap the ashmem");
+ }
+ char* cursor = reinterpret_cast<char*>(data.get());
+ int remaining = contentSize;
while (remaining > 0) {
int ret = TEMP_FAILURE_RETRY(write(wfd.get(), cursor, remaining));
if (ret < 0) {
- munmap(data, size);
return error("Failed to write to " + filePath + " (" + std::to_string(remaining) +
- + "/" + std::to_string(size) + "): " + strerror(errno));
+ + "/" + std::to_string(contentSize) + ")");
}
cursor += ret;
remaining -= ret;
}
- munmap(data, size);
+ wfd.reset();
- // 3. Enable fsverity. Once it's done, the file becomes immutable.
- struct fsverity_set config;
- config.offset = st.st_size;
- config.flags = FSVERITY_FLAG_ENABLED;
- if (ioctl(wfd.get(), FS_IOC_SET_FSVERITY, &config) < 0) {
- return error("Failed to enable fsverity on " + filePath + ": " + strerror(errno));
+ // 3. Enable fsverity (needs readonly fd. Once it's done, the file becomes immutable.
+ ::android::base::unique_fd rfd(open(filePath.c_str(), O_RDONLY));
+ if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, nullptr) < 0) {
+ return error("Failed to enable fsverity on " + filePath);
}
return ok();
}
@@ -2516,17 +2527,19 @@
std::to_string(expectedHash.size()));
}
- // TODO(71871109): Validate filePath.
::android::base::unique_fd fd(open(filePath.c_str(), O_RDONLY));
if (fd.get() < 0) {
return error("Failed to open " + filePath + ": " + strerror(errno));
}
- struct fsverity_root_hash config;
- memset(&config, 0, sizeof(config));
- config.root_hash_algorithm = 0; // SHA256
- memcpy(config.root_hash, expectedHash.data(), std::min(sizeof(config.root_hash), kSha256Size));
- if (ioctl(fd.get(), FS_IOC_MEASURE_FSVERITY, &config) < 0) {
+ unsigned int buffer_size = sizeof(fsverity_measurement) + kSha256Size;
+ std::vector<char> buffer(buffer_size, 0);
+
+ fsverity_measurement* config = reinterpret_cast<fsverity_measurement*>(buffer.data());
+ config->digest_algorithm = FS_VERITY_ALG_SHA256;
+ config->digest_size = kSha256Size;
+ memcpy(config->digest, expectedHash.data(), kSha256Size);
+ if (ioctl(fd.get(), FS_IOC_SET_VERITY_MEASUREMENT, config) < 0) {
// This includes an expected failure case with no FSVerity setup. It normally happens when
// the apk does not contains the Merkle tree root hash.
return error("Failed to measure fsverity on " + filePath + ": " + strerror(errno));
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 2a31967..cebd3f9 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -123,7 +123,7 @@
binder::Status deleteOdex(const std::string& apkPath, const std::string& instructionSet,
const std::unique_ptr<std::string>& outputPath);
binder::Status installApkVerity(const std::string& filePath,
- const ::android::base::unique_fd& verityInput);
+ const ::android::base::unique_fd& verityInput, int32_t contentSize);
binder::Status assertFsverityRootHashMatches(const std::string& filePath,
const std::vector<uint8_t>& expectedHash);
binder::Status reconcileSecondaryDexFile(const std::string& dexPath,
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 0c364bd..91e20b7 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -85,7 +85,8 @@
@utf8InCpp String outputPath);
void deleteOdex(@utf8InCpp String apkPath, @utf8InCpp String instructionSet,
@nullable @utf8InCpp String outputPath);
- void installApkVerity(@utf8InCpp String filePath, in FileDescriptor verityInput);
+ void installApkVerity(@utf8InCpp String filePath, in FileDescriptor verityInput,
+ int contentSize);
void assertFsverityRootHashMatches(@utf8InCpp String filePath, in byte[] expectedHash);
boolean reconcileSecondaryDexFile(@utf8InCpp String dexPath, @utf8InCpp String pkgName,
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index bab6a71..93cb849 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -453,7 +453,11 @@
tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]);
auto const surface = static_cast<Surface*>(window);
android_dataspace dataspace = surface->getBuffersDataSpace();
- result.appendFormat(" dataspace: %s (%d)\n", dataspaceDetails(dataspace).c_str(), dataspace);
+ result.appendFormat(" wideColor=%d, hdr=%d, colorMode=%s, dataspace: %s (%d)\n",
+ mDisplayHasWideColor, mDisplayHasHdr,
+ decodeColorMode(mActiveColorMode).c_str(),
+ dataspaceDetails(dataspace).c_str(), dataspace);
+
String8 surfaceDump;
mDisplaySurface->dumpAsString(surfaceDump);
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 4faba3b..9398bde 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -177,9 +177,9 @@
void FramebufferSurface::dumpAsString(String8& result) const {
Mutex::Autolock lock(mMutex);
- result.appendFormat("FramebufferSurface: dataspace: %s(%d)\n",
+ result.appendFormat(" FramebufferSurface: dataspace: %s(%d)\n",
dataspaceDetails(mDataSpace).c_str(), mDataSpace);
- ConsumerBase::dumpLocked(result, "");
+ ConsumerBase::dumpLocked(result, " ");
}
void FramebufferSurface::dumpLocked(String8& result, const char* prefix) const
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 73e7b05..166ac22 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1488,7 +1488,11 @@
const Layer::State& layerState(getDrawingState());
const LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers.at(hwcId);
- result.appendFormat(" %10d | ", layerState.z);
+ if (layerState.zOrderRelativeOf != nullptr || mDrawingParent != nullptr) {
+ result.appendFormat(" rel %6d | ", layerState.z);
+ } else {
+ result.appendFormat(" %10d | ", layerState.z);
+ }
result.appendFormat("%10s | ", to_string(getCompositionType(hwcId)).c_str());
const Rect& frame = hwcInfo.displayFrame;
result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
diff --git a/services/surfaceflinger/RenderEngine/Surface.cpp b/services/surfaceflinger/RenderEngine/Surface.cpp
index 3c29e4b..0d20f1f 100644
--- a/services/surfaceflinger/RenderEngine/Surface.cpp
+++ b/services/surfaceflinger/RenderEngine/Surface.cpp
@@ -66,7 +66,7 @@
EGLint Surface::queryConfig(EGLint attrib) const {
EGLint value;
- if (!eglGetConfigAttrib(mEGLConfig, mEGLConfig, attrib, &value)) {
+ if (!eglGetConfigAttrib(mEGLDisplay, mEGLConfig, attrib, &value)) {
value = 0;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 09e67b6..f180a3b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4049,6 +4049,7 @@
LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str());
+ result.append("\n");
/*
* Dump Display state
@@ -4061,6 +4062,7 @@
const sp<const DisplayDevice>& hw(mDisplays[dpy]);
hw->dump(result);
}
+ result.append("\n");
/*
* Dump SurfaceFlinger global state
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index 47e5d1f..1383d28 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -273,7 +273,7 @@
finalCrop.to_string().c_str());
StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
- StringAppendF(&result, "pixelformat=%s, ", pixelFormat.c_str());
+ StringAppendF(&result, "defaultPixelFormat=%s, ", pixelFormat.c_str());
StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
static_cast<double>(color.r), static_cast<double>(color.g),
static_cast<double>(color.b), static_cast<double>(color.a), flags);
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index dec39e0..741fbb8 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -500,13 +500,36 @@
// both we and HAL can take part in
hook_extensions_.set(ext_bit);
break;
- case ProcHook::EXTENSION_UNKNOWN:
case ProcHook::KHR_get_physical_device_properties2:
- // HAL's extensions
+ case ProcHook::EXTENSION_UNKNOWN:
+ // Extensions we don't need to do anything about at this level
break;
- default:
- ALOGW("Ignored invalid instance extension %s", name);
+
+ case ProcHook::KHR_incremental_present:
+ case ProcHook::KHR_shared_presentable_image:
+ case ProcHook::KHR_swapchain:
+ case ProcHook::EXT_hdr_metadata:
+ case ProcHook::ANDROID_external_memory_android_hardware_buffer:
+ case ProcHook::ANDROID_native_buffer:
+ case ProcHook::GOOGLE_display_timing:
+ case ProcHook::EXTENSION_CORE:
+ case ProcHook::EXTENSION_COUNT:
+ // Device and meta extensions. If we ever get here it's a bug in
+ // our code. But enumerating them lets us avoid having a default
+ // case, and default hides other bugs.
+ ALOGE(
+ "CreateInfoWrapper::FilterExtension: invalid instance "
+ "extension '%s'. FIX ME",
+ name);
return;
+
+ // Don't use a default case. Without it, -Wswitch will tell us
+ // at compile time if someone adds a new ProcHook extension but
+ // doesn't handle it above. That's a real bug that has
+ // not-immediately-obvious effects.
+ //
+ // default:
+ // break;
}
} else {
switch (ext_bit) {
@@ -524,12 +547,36 @@
case ProcHook::EXT_hdr_metadata:
hook_extensions_.set(ext_bit);
break;
+ case ProcHook::ANDROID_external_memory_android_hardware_buffer:
case ProcHook::EXTENSION_UNKNOWN:
- // HAL's extensions
+ // Extensions we don't need to do anything about at this level
break;
- default:
- ALOGW("Ignored invalid device extension %s", name);
+
+ case ProcHook::KHR_android_surface:
+ case ProcHook::KHR_get_physical_device_properties2:
+ case ProcHook::KHR_get_surface_capabilities2:
+ case ProcHook::KHR_surface:
+ case ProcHook::EXT_debug_report:
+ case ProcHook::EXT_swapchain_colorspace:
+ case ProcHook::ANDROID_native_buffer:
+ case ProcHook::EXTENSION_CORE:
+ case ProcHook::EXTENSION_COUNT:
+ // Instance and meta extensions. If we ever get here it's a bug
+ // in our code. But enumerating them lets us avoid having a
+ // default case, and default hides other bugs.
+ ALOGE(
+ "CreateInfoWrapper::FilterExtension: invalid device "
+ "extension '%s'. FIX ME",
+ name);
return;
+
+ // Don't use a default case. Without it, -Wswitch will tell us
+ // at compile time if someone adds a new ProcHook extension but
+ // doesn't handle it above. That's a real bug that has
+ // not-immediately-obvious effects.
+ //
+ // default:
+ // break;
}
}