Merge changes Id01e6771,I7e53a8a2
* changes:
swapchain: Implement VK_KHR_surface_protected_capabilities
swapchain: Implement VK_GOOGLE_surfaceless_query
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 0e9ce89..24b201f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -2418,7 +2418,7 @@
// Given that bugreport is required to diagnose failures, it's better to set an arbitrary amount
// of timeout for IDumpstateDevice than to block the rest of bugreport. In the timeout case, we
// will kill the HAL and grab whatever it dumped in time.
- constexpr size_t timeout_sec = 30;
+ constexpr size_t timeout_sec = 45;
if (dumpstate_hal_handle_aidl != nullptr) {
DoDumpstateBoardAidl(dumpstate_hal_handle_aidl, dumpstate_fds, options_->bugreport_mode,
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index e1cbc19..8132d46 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -18,10 +18,13 @@
#include <errno.h>
#include <fcntl.h>
+#include <linux/memfd.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <sys/stat.h>
+#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
@@ -34,6 +37,24 @@
// ---------------------------------------------------------------------------
+#ifdef __BIONIC__
+static int memfd_create_region(const char* name, size_t size) {
+ int fd = memfd_create(name, MFD_CLOEXEC | MFD_ALLOW_SEALING);
+ if (fd == -1) {
+ ALOGE("%s: memfd_create(%s, %zd) failed: %s\n", __func__, name, size, strerror(errno));
+ return -1;
+ }
+
+ if (ftruncate(fd, size) == -1) {
+ ALOGE("%s, ftruncate(%s, %zd) failed for memfd creation: %s\n", __func__, name, size,
+ strerror(errno));
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+#endif
+
MemoryHeapBase::MemoryHeapBase()
: mFD(-1), mSize(0), mBase(MAP_FAILED),
mDevice(nullptr), mNeedUnmap(false), mOffset(0)
@@ -45,15 +66,36 @@
mDevice(nullptr), mNeedUnmap(false), mOffset(0)
{
const size_t pagesize = getpagesize();
- size = ((size + pagesize-1) & ~(pagesize-1));
- int fd = ashmem_create_region(name == nullptr ? "MemoryHeapBase" : name, size);
- ALOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
- if (fd >= 0) {
- if (mapfd(fd, true, size) == NO_ERROR) {
- if (flags & READ_ONLY) {
- ashmem_set_prot_region(fd, PROT_READ);
- }
+ size = ((size + pagesize - 1) & ~(pagesize - 1));
+ int fd = -1;
+ if (mFlags & FORCE_MEMFD) {
+#ifdef __BIONIC__
+ ALOGV("MemoryHeapBase: Attempting to force MemFD");
+ fd = memfd_create_region(name ? name : "MemoryHeapBase", size);
+ if (fd < 0 || (mapfd(fd, true, size) != NO_ERROR)) return;
+ const int SEAL_FLAGS = ((mFlags & READ_ONLY) ? F_SEAL_FUTURE_WRITE : 0) |
+ ((mFlags & MEMFD_ALLOW_SEALING) ? 0 : F_SEAL_SEAL);
+ if (SEAL_FLAGS && (fcntl(fd, F_ADD_SEALS, SEAL_FLAGS) == -1)) {
+ ALOGE("MemoryHeapBase: MemFD %s sealing with flags %x failed with error %s", name,
+ SEAL_FLAGS, strerror(errno));
+ munmap(mBase, mSize);
+ mBase = nullptr;
+ mSize = 0;
+ close(fd);
}
+ return;
+#else
+ mFlags &= ~(FORCE_MEMFD | MEMFD_ALLOW_SEALING);
+#endif
+ }
+ if (mFlags & MEMFD_ALLOW_SEALING) {
+ LOG_ALWAYS_FATAL("Invalid Flags. MEMFD_ALLOW_SEALING only valid with FORCE_MEMFD.");
+ }
+ fd = ashmem_create_region(name ? name : "MemoryHeapBase", size);
+ ALOGE_IF(fd < 0, "MemoryHeapBase: error creating ashmem region: %s", strerror(errno));
+ if (fd < 0 || (mapfd(fd, true, size) != NO_ERROR)) return;
+ if (mFlags & READ_ONLY) {
+ ashmem_set_prot_region(fd, PROT_READ);
}
}
@@ -61,6 +103,9 @@
: mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
mDevice(nullptr), mNeedUnmap(false), mOffset(0)
{
+ if (flags & (FORCE_MEMFD | MEMFD_ALLOW_SEALING)) {
+ LOG_ALWAYS_FATAL("FORCE_MEMFD, MEMFD_ALLOW_SEALING only valid with creating constructor");
+ }
int open_flags = O_RDWR;
if (flags & NO_CACHING)
open_flags |= O_SYNC;
@@ -80,6 +125,9 @@
: mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
mDevice(nullptr), mNeedUnmap(false), mOffset(0)
{
+ if (flags & (FORCE_MEMFD | MEMFD_ALLOW_SEALING)) {
+ LOG_ALWAYS_FATAL("FORCE_MEMFD, MEMFD_ALLOW_SEALING only valid with creating constructor");
+ }
const size_t pagesize = getpagesize();
size = ((size + pagesize-1) & ~(pagesize-1));
mapfd(fcntl(fd, F_DUPFD_CLOEXEC, 0), false, size, offset);
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index e79cb86..d40778a 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -853,10 +853,16 @@
}
if (session->mConnections.mOutgoing.size() == 0) {
- ALOGE("Session has no client connections. This is required for an RPC server to make "
- "any non-nested (e.g. oneway or on another thread) calls. Use: %d. Server "
- "connections: %zu",
- static_cast<int>(use), session->mConnections.mIncoming.size());
+ ALOGE("Session has no outgoing connections. This is required for an RPC server to make "
+ "any non-nested (e.g. oneway or on another thread) calls. Use code request "
+ "reason: %d. Incoming connections: %zu. %s.",
+ static_cast<int>(use), session->mConnections.mIncoming.size(),
+ (session->server()
+ ? "This is a server session, so see RpcSession::setMaxIncomingThreads "
+ "for the corresponding client"
+ : "This is a client session, so see RpcSession::setMaxOutgoingThreads "
+ "for this client or RpcServer::setMaxThreads for the corresponding "
+ "server"));
return WOULD_BLOCK;
}
diff --git a/libs/binder/include/binder/MemoryHeapBase.h b/libs/binder/include/binder/MemoryHeapBase.h
index dd76943..15dd28f 100644
--- a/libs/binder/include/binder/MemoryHeapBase.h
+++ b/libs/binder/include/binder/MemoryHeapBase.h
@@ -34,7 +34,21 @@
// memory won't be mapped locally, but will be mapped in the remote
// process.
DONT_MAP_LOCALLY = 0x00000100,
- NO_CACHING = 0x00000200
+ NO_CACHING = 0x00000200,
+ // Bypass ashmem-libcutils to create a memfd shared region.
+ // Ashmem-libcutils will eventually migrate to memfd.
+ // Memfd has security benefits and supports file sealing.
+ // Calling process will need to modify selinux permissions to
+ // open access to tmpfs files. See audioserver for examples.
+ // This is only valid for size constructor.
+ // For host compilation targets, memfd is stubbed in favor of /tmp
+ // files so sealing is not enforced.
+ FORCE_MEMFD = 0x00000400,
+ // Default opt-out of sealing behavior in memfd to avoid potential DOS.
+ // Clients of shared files can seal at anytime via syscall, leading to
+ // TOC/TOU issues if additional seals prevent access from the creating
+ // process. Alternatively, seccomp fcntl().
+ MEMFD_ALLOW_SEALING = 0x00000800
};
/*
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index ff55d6e..a3533d8 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -99,6 +99,7 @@
"binderParcelUnitTest.cpp",
"binderBinderUnitTest.cpp",
"binderStatusUnitTest.cpp",
+ "binderMemoryHeapBaseUnitTest.cpp",
],
shared_libs: [
"libbinder",
diff --git a/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp b/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp
new file mode 100644
index 0000000..21cb70b
--- /dev/null
+++ b/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/MemoryHeapBase.h>
+#include <cutils/ashmem.h>
+#include <fcntl.h>
+
+#include <gtest/gtest.h>
+using namespace android;
+#ifdef __BIONIC__
+TEST(MemoryHeapBase, ForceMemfdRespected) {
+ auto mHeap = sp<MemoryHeapBase>::make(10, MemoryHeapBase::FORCE_MEMFD, "Test mapping");
+ int fd = mHeap->getHeapID();
+ EXPECT_NE(fd, -1);
+ EXPECT_FALSE(ashmem_valid(fd));
+ EXPECT_NE(fcntl(fd, F_GET_SEALS), -1);
+}
+
+TEST(MemoryHeapBase, MemfdSealed) {
+ auto mHeap = sp<MemoryHeapBase>::make(8192,
+ MemoryHeapBase::FORCE_MEMFD,
+ "Test mapping");
+ int fd = mHeap->getHeapID();
+ EXPECT_NE(fd, -1);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_SEAL);
+}
+
+TEST(MemoryHeapBase, MemfdUnsealed) {
+ auto mHeap = sp<MemoryHeapBase>::make(8192,
+ MemoryHeapBase::FORCE_MEMFD |
+ MemoryHeapBase::MEMFD_ALLOW_SEALING,
+ "Test mapping");
+ int fd = mHeap->getHeapID();
+ EXPECT_NE(fd, -1);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), 0);
+}
+
+TEST(MemoryHeapBase, MemfdSealedProtected) {
+ auto mHeap = sp<MemoryHeapBase>::make(8192,
+ MemoryHeapBase::FORCE_MEMFD |
+ MemoryHeapBase::READ_ONLY,
+ "Test mapping");
+ int fd = mHeap->getHeapID();
+ EXPECT_NE(fd, -1);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_SEAL | F_SEAL_FUTURE_WRITE);
+}
+
+TEST(MemoryHeapBase, MemfdUnsealedProtected) {
+ auto mHeap = sp<MemoryHeapBase>::make(8192,
+ MemoryHeapBase::FORCE_MEMFD |
+ MemoryHeapBase::READ_ONLY |
+ MemoryHeapBase::MEMFD_ALLOW_SEALING,
+ "Test mapping");
+ int fd = mHeap->getHeapID();
+ EXPECT_NE(fd, -1);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_FUTURE_WRITE);
+}
+
+#else
+TEST(MemoryHeapBase, HostMemfdExpected) {
+ auto mHeap = sp<MemoryHeapBase>::make(8192,
+ MemoryHeapBase::READ_ONLY,
+ "Test mapping");
+ int fd = mHeap->getHeapID();
+ void* ptr = mHeap->getBase();
+ EXPECT_NE(ptr, MAP_FAILED);
+ EXPECT_TRUE(ashmem_valid(fd));
+ EXPECT_EQ(mHeap->getFlags(), MemoryHeapBase::READ_ONLY);
+}
+
+TEST(MemoryHeapBase,HostMemfdException) {
+ auto mHeap = sp<MemoryHeapBase>::make(8192,
+ MemoryHeapBase::FORCE_MEMFD |
+ MemoryHeapBase::READ_ONLY |
+ MemoryHeapBase::MEMFD_ALLOW_SEALING,
+ "Test mapping");
+ int fd = mHeap->getHeapID();
+ void* ptr = mHeap->getBase();
+ EXPECT_EQ(mHeap->getFlags(), MemoryHeapBase::READ_ONLY);
+ EXPECT_TRUE(ashmem_valid(fd));
+ EXPECT_NE(ptr, MAP_FAILED);
+}
+
+#endif