Merge changes Ic90fac0b,Id9c12303,I2d9bdcb1,I9d699af1,Ia4d03f9e, ...
* changes:
adbd: turn on fdsan warnings.
adb: add error-generating overload of adb_close(unique_fd).
adb: fix register_socket_transport related double-closes.
adb: fix double close in local_connect_arbitrary_ports.
adb: use adb's unique_fd instead of android::base.
adb: move remount_service.h into daemon.
adb: split shell_service.h into client/daemon/protocol parts.
adb: split file_sync_service.h into client and daemon parts.
diff --git a/fastboot/usb.h b/fastboot/usb.h
index 96eb934..7ca44c4 100644
--- a/fastboot/usb.h
+++ b/fastboot/usb.h
@@ -55,6 +55,7 @@
class UsbTransport : public Transport {
// Resets the underlying transport. Returns 0 on success.
// This effectively simulates unplugging and replugging
+ public:
virtual int Reset() = 0;
};
diff --git a/fastboot/usb_osx.cpp b/fastboot/usb_osx.cpp
index 442dea5..4d48f6e 100644
--- a/fastboot/usb_osx.cpp
+++ b/fastboot/usb_osx.cpp
@@ -67,7 +67,8 @@
class OsxUsbTransport : public UsbTransport {
public:
- OsxUsbTransport(std::unique_ptr<usb_handle> handle, uint32_t ms_timeout)
+ // A timeout of 0 is blocking
+ OsxUsbTransport(std::unique_ptr<usb_handle> handle, uint32_t ms_timeout = 0)
: handle_(std::move(handle)), ms_timeout_(ms_timeout) {}
~OsxUsbTransport() override = default;
@@ -475,15 +476,17 @@
return 0;
}
+/*
+ TODO: this SHOULD be easy to do with ResetDevice() from IOUSBDeviceInterface.
+ However to perform operations that manipulate the state of the device, you must
+ claim ownership of the device with USBDeviceOpenSeize(). However, this operation
+ always fails with kIOReturnExclusiveAccess.
+ It seems that the kext com.apple.driver.usb.AppleUSBHostCompositeDevice
+ always loads and claims ownership of the device and refuses to give it up.
+*/
int OsxUsbTransport::Reset() {
- IOReturn result = (*handle_->interface)->ResetDevice(handle_->interface);
-
- if (result == 0) {
- return 0;
- } else {
- ERR("usb_reset failed with status %x\n", result);
- return -1;
- }
+ ERR("USB reset is currently unsupported on osx\n");
+ return -1;
}
ssize_t OsxUsbTransport::Read(void* data, size_t len) {
@@ -508,9 +511,14 @@
return -1;
}
- result = (*handle_->interface)
- ->ReadPipeTO(handle_->interface, handle_->bulkIn, data, &numBytes,
- USB_TRANSACTION_TIMEOUT, USB_TRANSACTION_TIMEOUT);
+ if (!ms_timeout_) {
+ result = (*handle_->interface)
+ ->ReadPipe(handle_->interface, handle_->bulkIn, data, &numBytes);
+ } else {
+ result = (*handle_->interface)
+ ->ReadPipeTO(handle_->interface, handle_->bulkIn, data, &numBytes,
+ ms_timeout_, ms_timeout_);
+ }
if (result == 0) {
return (int) numBytes;
@@ -557,8 +565,16 @@
int lenToSend = lenRemaining > maxLenToSend
? maxLenToSend : lenRemaining;
- result = (*handle_->interface)->WritePipe(
- handle_->interface, handle_->bulkOut, (void *)data, lenToSend);
+ if (!ms_timeout_) { // blocking
+ result = (*handle_->interface)
+ ->WritePipe(handle_->interface, handle_->bulkOut, (void*)data,
+ lenToSend);
+ } else {
+ result = (*handle_->interface)
+ ->WritePipeTO(handle_->interface, handle_->bulkOut, (void*)data,
+ lenToSend, ms_timeout_, ms_timeout_);
+ }
+
if (result != 0) break;
lenRemaining -= lenToSend;
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index a3ce879..bf69096 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -30,7 +30,7 @@
],
}
-cc_library_static {
+cc_library {
name: "libfs_mgr",
defaults: ["fs_mgr_defaults"],
recovery_available: true,
@@ -44,15 +44,20 @@
"fs_mgr_avb_ops.cpp",
"fs_mgr_dm_linear.cpp",
],
- static_libs: [
+ shared_libs: [
"libfec",
"libfec_rs",
"libbase",
"libcrypto_utils",
"libcrypto",
+ "libcutils",
"libext4_utils",
+ "libkeyutils",
+ "liblog",
"libsquashfs_utils",
"libselinux",
+ ],
+ static_libs: [
"libavb",
"libfstab",
"libdm",
diff --git a/fs_mgr/libdm/dm_target.cpp b/fs_mgr/libdm/dm_target.cpp
index 20b26df..7c18267 100644
--- a/fs_mgr/libdm/dm_target.cpp
+++ b/fs_mgr/libdm/dm_target.cpp
@@ -111,5 +111,9 @@
return base + " " + std::to_string(optional_args_.size()) + " " + optional;
}
+std::string DmTargetAndroidVerity::GetParameterString() const {
+ return keyid_ + " " + block_device_;
+}
+
} // namespace dm
} // namespace android
diff --git a/fs_mgr/libdm/include/libdm/dm_target.h b/fs_mgr/libdm/include/libdm/dm_target.h
index d5974f4..31863c8 100644
--- a/fs_mgr/libdm/include/libdm/dm_target.h
+++ b/fs_mgr/libdm/include/libdm/dm_target.h
@@ -128,6 +128,20 @@
bool valid_;
};
+class DmTargetAndroidVerity final : public DmTarget {
+ public:
+ DmTargetAndroidVerity(uint64_t start, uint64_t length, const std::string& block_device,
+ const std::string& keyid)
+ : DmTarget(start, length), keyid_(keyid), block_device_(block_device) {}
+
+ std::string name() const override { return "android-verity"; }
+ std::string GetParameterString() const override;
+
+ private:
+ std::string keyid_;
+ std::string block_device_;
+};
+
// This is the same as DmTargetVerity, but the table may be specified as a raw
// string. This code exists only for fs_mgr_verity and should be avoided. Use
// DmTargetVerity for new code instead.
diff --git a/fs_mgr/tools/dmctl.cpp b/fs_mgr/tools/dmctl.cpp
index 5e11c84..45a81af 100644
--- a/fs_mgr/tools/dmctl.cpp
+++ b/fs_mgr/tools/dmctl.cpp
@@ -40,6 +40,7 @@
using DmTarget = ::android::dm::DmTarget;
using DmTargetLinear = ::android::dm::DmTargetLinear;
using DmTargetZero = ::android::dm::DmTargetZero;
+using DmTargetAndroidVerity = ::android::dm::DmTargetAndroidVerity;
using DmTargetTypeInfo = ::android::dm::DmTargetTypeInfo;
using DmBlockDevice = ::android::dm::DeviceMapper::DmBlockDevice;
@@ -96,6 +97,16 @@
}
return std::make_unique<DmTargetLinear>(start_sector, num_sectors, block_device,
physical_sector);
+ } else if (target_type == "android-verity") {
+ if (!HasArgs(2)) {
+ std::cerr << "Expected \"android-verity\" <public-key-id> <block_device>"
+ << std::endl;
+ return nullptr;
+ }
+ std::string keyid = NextArg();
+ std::string block_device = NextArg();
+ return std::make_unique<DmTargetAndroidVerity>(start_sector, num_sectors, keyid,
+ block_device);
} else {
std::cerr << "Unrecognized target type: " << target_type << std::endl;
return nullptr;
@@ -132,11 +143,11 @@
while (arg_index < argc && argv[arg_index][0] == '-') {
if (strcmp(argv[arg_index], "-ro") == 0) {
table.set_readonly(true);
+ arg_index++;
} else {
std::cerr << "Unrecognized option: " << argv[arg_index] << std::endl;
return -EINVAL;
}
- arg_index++;
}
// Parse everything else as target information.
diff --git a/gatekeeperd/OWNERS b/gatekeeperd/OWNERS
new file mode 100644
index 0000000..9c99c6e
--- /dev/null
+++ b/gatekeeperd/OWNERS
@@ -0,0 +1,2 @@
+swillden@google.com
+jdanis@google.com
diff --git a/init/action_parser.cpp b/init/action_parser.cpp
index 8a4b518..1481162 100644
--- a/init/action_parser.cpp
+++ b/init/action_parser.cpp
@@ -60,7 +60,7 @@
prop_name.erase(equal_pos);
if (!IsActionableProperty(subcontext, prop_name)) {
- return Error() << "unexported property tigger found: " << prop_name;
+ return Error() << "unexported property trigger found: " << prop_name;
}
if (auto [it, inserted] = property_triggers->emplace(prop_name, prop_value); !inserted) {
diff --git a/liblog/include/log/log_main.h b/liblog/include/log/log_main.h
index 9c68ff2..1314330 100644
--- a/liblog/include/log/log_main.h
+++ b/liblog/include/log/log_main.h
@@ -47,7 +47,8 @@
* so don't link with __clang_analyzer__ defined.
*/
#ifdef __clang_analyzer__
-extern void __FAKE_USE_VA_ARGS(...);
+extern void __fake_use_va_args(int, ...);
+#define __FAKE_USE_VA_ARGS(...) __fake_use_va_args(0, ##__VA_ARGS__)
#else
#define __FAKE_USE_VA_ARGS(...) ((void)(0))
#endif
diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp
index 87e2684..835e226 100644
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -42,7 +42,7 @@
FrameworkListener::FrameworkListener(int sock) :
SocketListener(sock, true) {
- init(NULL, false);
+ init(nullptr, false);
}
void FrameworkListener::init(const char *socketName UNUSED, bool withSeq) {
@@ -154,7 +154,7 @@
if (!haveCmdNum) {
char *endptr;
int cmdNum = (int)strtol(tmp, &endptr, 0);
- if (endptr == NULL || *endptr != '\0') {
+ if (endptr == nullptr || *endptr != '\0') {
cli->sendMsg(500, "Invalid sequence number", false);
goto out;
}
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index f0c66ec..24ea7aa 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -45,8 +45,8 @@
NetlinkEvent::NetlinkEvent() {
mAction = Action::kUnknown;
memset(mParams, 0, sizeof(mParams));
- mPath = NULL;
- mSubsystem = NULL;
+ mPath = nullptr;
+ mSubsystem = nullptr;
}
NetlinkEvent::~NetlinkEvent() {
@@ -89,7 +89,7 @@
NL_EVENT_RTM_NAME(LOCAL_QLOG_NL_EVENT);
NL_EVENT_RTM_NAME(LOCAL_NFLOG_PACKET);
default:
- return NULL;
+ return nullptr;
}
#undef NL_EVENT_RTM_NAME
}
@@ -158,7 +158,7 @@
*/
bool NetlinkEvent::parseIfAddrMessage(const struct nlmsghdr *nh) {
struct ifaddrmsg *ifaddr = (struct ifaddrmsg *) NLMSG_DATA(nh);
- struct ifa_cacheinfo *cacheinfo = NULL;
+ struct ifa_cacheinfo *cacheinfo = nullptr;
char addrstr[INET6_ADDRSTRLEN] = "";
char ifname[IFNAMSIZ] = "";
@@ -286,7 +286,7 @@
bool NetlinkEvent::parseNfPacketMessage(struct nlmsghdr *nh) {
int uid = -1;
int len = 0;
- char* raw = NULL;
+ char* raw = nullptr;
struct nlattr* uid_attr = findNlAttr(nh, sizeof(struct genlmsghdr), NFULA_UID);
if (uid_attr) {
@@ -584,7 +584,7 @@
(prefixlen == 0 || !memcmp(str, prefix, prefixlen))) {
return str + prefixlen;
} else {
- return NULL;
+ return nullptr;
}
}
@@ -625,16 +625,16 @@
first = 0;
} else {
const char* a;
- if ((a = HAS_CONST_PREFIX(s, end, "ACTION=")) != NULL) {
+ if ((a = HAS_CONST_PREFIX(s, end, "ACTION=")) != nullptr) {
if (!strcmp(a, "add"))
mAction = Action::kAdd;
else if (!strcmp(a, "remove"))
mAction = Action::kRemove;
else if (!strcmp(a, "change"))
mAction = Action::kChange;
- } else if ((a = HAS_CONST_PREFIX(s, end, "SEQNUM=")) != NULL) {
+ } else if ((a = HAS_CONST_PREFIX(s, end, "SEQNUM=")) != nullptr) {
mSeq = atoi(a);
- } else if ((a = HAS_CONST_PREFIX(s, end, "SUBSYSTEM=")) != NULL) {
+ } else if ((a = HAS_CONST_PREFIX(s, end, "SUBSYSTEM=")) != nullptr) {
mSubsystem = strdup(a);
} else if (param_idx < NL_PARAMS_MAX) {
mParams[param_idx++] = strdup(s);
@@ -656,14 +656,14 @@
const char *NetlinkEvent::findParam(const char *paramName) {
size_t len = strlen(paramName);
- for (int i = 0; i < NL_PARAMS_MAX && mParams[i] != NULL; ++i) {
+ for (int i = 0; i < NL_PARAMS_MAX && mParams[i] != nullptr; ++i) {
const char *ptr = mParams[i] + len;
if (!strncmp(mParams[i], paramName, len) && *ptr == '=')
return ++ptr;
}
SLOGE("NetlinkEvent::FindParam(): Parameter '%s' not found", paramName);
- return NULL;
+ return nullptr;
}
nlattr* NetlinkEvent::findNlAttr(const nlmsghdr* nh, size_t hdrlen, uint16_t attr) {
diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp
index 971f908..0625db7 100644
--- a/libsysutils/src/SocketClient.cpp
+++ b/libsysutils/src/SocketClient.cpp
@@ -42,8 +42,8 @@
mSocket = socket;
mSocketOwned = owned;
mUseCmdNum = useCmdNum;
- pthread_mutex_init(&mWriteMutex, NULL);
- pthread_mutex_init(&mRefCountMutex, NULL);
+ pthread_mutex_init(&mWriteMutex, nullptr);
+ pthread_mutex_init(&mRefCountMutex, nullptr);
mPid = -1;
mUid = -1;
mGid = -1;
@@ -135,9 +135,9 @@
const char *end = arg + len;
char *oldresult;
- if(result == NULL) {
+ if(result == nullptr) {
SLOGW("malloc error (%s)", strerror(errno));
- return NULL;
+ return nullptr;
}
*(current++) = '"';
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index 3f8f3db..0c8a688 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -39,7 +39,7 @@
}
SocketListener::SocketListener(int socketFd, bool listen) {
- init(NULL, socketFd, listen, false);
+ init(nullptr, socketFd, listen, false);
}
SocketListener::SocketListener(const char *socketName, bool listen, bool useCmdNum) {
@@ -51,7 +51,7 @@
mSocketName = socketName;
mSock = socketFd;
mUseCmdNum = useCmdNum;
- pthread_mutex_init(&mClientsLock, NULL);
+ pthread_mutex_init(&mClientsLock, nullptr);
mClients = new SocketClientCollection();
}
@@ -102,7 +102,7 @@
return -1;
}
- if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) {
+ if (pthread_create(&mThread, nullptr, SocketListener::threadStart, this)) {
SLOGE("pthread_create (%s)", strerror(errno));
return -1;
}
@@ -147,8 +147,8 @@
SocketListener *me = reinterpret_cast<SocketListener *>(obj);
me->runListener();
- pthread_exit(NULL);
- return NULL;
+ pthread_exit(nullptr);
+ return nullptr;
}
void SocketListener::runListener() {
@@ -183,7 +183,7 @@
}
pthread_mutex_unlock(&mClientsLock);
SLOGV("mListen=%d, max=%d, mSocketName=%s", mListen, max, mSocketName);
- if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) {
+ if ((rc = select(max + 1, &read_fds, nullptr, nullptr, nullptr)) < 0) {
if (errno == EINTR)
continue;
SLOGE("select failed (%s) mListen=%d, max=%d", strerror(errno), mListen, max);
diff --git a/libunwindstack/DexFile.cpp b/libunwindstack/DexFile.cpp
index b18b0ce..3d982f6 100644
--- a/libunwindstack/DexFile.cpp
+++ b/libunwindstack/DexFile.cpp
@@ -68,17 +68,51 @@
return false; // The DEX offset is not within the bytecode of this dex file.
}
- for (uint32_t i = 0; i < dex_file_->NumClassDefs(); ++i) {
- const art::DexFile::ClassDef& class_def = dex_file_->GetClassDef(i);
+ if (dex_file_->IsCompactDexFile()) {
+ // The data section of compact dex files might be shared.
+ // Check the subrange unique to this compact dex.
+ const auto& cdex_header = dex_file_->AsCompactDexFile()->GetHeader();
+ uint32_t begin = cdex_header.data_off_ + cdex_header.OwnedDataBegin();
+ uint32_t end = cdex_header.data_off_ + cdex_header.OwnedDataEnd();
+ if (dex_offset < begin || dex_offset >= end) {
+ return false; // The DEX offset is not within the bytecode of this dex file.
+ }
+ }
+
+ // The method data is cached in a std::map indexed by method end offset and
+ // contains the start offset and the method member index.
+ // Only cache the method data as it is searched. Do not read the entire
+ // set of method data into the cache at once.
+ // This is done because many unwinds only find a single frame with dex file
+ // info, so reading the entire method data is wasteful. However, still cache
+ // the data so that anything doing multiple unwinds will have this data
+ // cached for future use.
+
+ // First look in the method cache.
+ auto entry = method_cache_.upper_bound(dex_offset);
+ if (entry != method_cache_.end() && dex_offset >= entry->second.first) {
+ *method_name = dex_file_->PrettyMethod(entry->second.second, false);
+ *method_offset = dex_offset - entry->second.first;
+ return true;
+ }
+
+ // Check the methods we haven't cached.
+ for (; class_def_index_ < dex_file_->NumClassDefs(); class_def_index_++) {
+ const art::DexFile::ClassDef& class_def = dex_file_->GetClassDef(class_def_index_);
const uint8_t* class_data = dex_file_->GetClassData(class_def);
if (class_data == nullptr) {
continue;
}
- for (art::ClassDataItemIterator it(*dex_file_.get(), class_data); it.HasNext(); it.Next()) {
- if (!it.IsAtMethod()) {
+
+ if (class_it_.get() == nullptr || !class_it_->HasNext()) {
+ class_it_.reset(new art::ClassDataItemIterator(*dex_file_.get(), class_data));
+ }
+
+ for (; class_it_->HasNext(); class_it_->Next()) {
+ if (!class_it_->IsAtMethod()) {
continue;
}
- const art::DexFile::CodeItem* code_item = it.GetMethodCodeItem();
+ const art::DexFile::CodeItem* code_item = class_it_->GetMethodCodeItem();
if (code_item == nullptr) {
continue;
}
@@ -87,11 +121,15 @@
continue;
}
- uint64_t offset = reinterpret_cast<const uint8_t*>(code.Insns()) - dex_file_->Begin();
- size_t size = code.InsnsSizeInCodeUnits() * sizeof(uint16_t);
- if (offset <= dex_offset && dex_offset < offset + size) {
- *method_name = dex_file_->PrettyMethod(it.GetMemberIndex(), false);
+ uint32_t offset = reinterpret_cast<const uint8_t*>(code.Insns()) - dex_file_->Begin();
+ uint32_t offset_end = offset + code.InsnsSizeInCodeUnits() * sizeof(uint16_t);
+ uint32_t member_index = class_it_->GetMemberIndex();
+ method_cache_[offset_end] = std::make_pair(offset, member_index);
+ if (offset <= dex_offset && dex_offset < offset_end) {
+ *method_name = dex_file_->PrettyMethod(member_index, false);
*method_offset = dex_offset - offset;
+ // Move past this element.
+ class_it_->Next();
return true;
}
}
diff --git a/libunwindstack/DexFile.h b/libunwindstack/DexFile.h
index 3ce2f1e..508692d 100644
--- a/libunwindstack/DexFile.h
+++ b/libunwindstack/DexFile.h
@@ -19,8 +19,10 @@
#include <stdint.h>
+#include <map>
#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include <dex/dex_file-inl.h>
@@ -37,7 +39,13 @@
static DexFile* Create(uint64_t dex_file_offset_in_memory, Memory* memory, MapInfo* info);
protected:
+ void Init();
+
std::unique_ptr<const art::DexFile> dex_file_;
+ std::map<uint32_t, std::pair<uint64_t, uint32_t>> method_cache_; // dex offset to method index.
+
+ uint32_t class_def_index_ = 0;
+ std::unique_ptr<art::ClassDataItemIterator> class_it_;
};
class DexFileFromFile : public DexFile {
diff --git a/libunwindstack/tests/DexFileTest.cpp b/libunwindstack/tests/DexFileTest.cpp
index 0b02c5b..4dd8cb0 100644
--- a/libunwindstack/tests/DexFileTest.cpp
+++ b/libunwindstack/tests/DexFileTest.cpp
@@ -206,15 +206,42 @@
std::string method;
uint64_t method_offset;
- dex_file->GetMethodInformation(0x102, &method, &method_offset);
+ ASSERT_TRUE(dex_file->GetMethodInformation(0x102, &method, &method_offset));
EXPECT_EQ("Main.<init>", method);
EXPECT_EQ(2U, method_offset);
- method = "not_in_a_method";
- method_offset = 0x123;
- dex_file->GetMethodInformation(0x100000, &method, &method_offset);
- EXPECT_EQ("not_in_a_method", method);
- EXPECT_EQ(0x123U, method_offset);
+ ASSERT_TRUE(dex_file->GetMethodInformation(0x118, &method, &method_offset));
+ EXPECT_EQ("Main.main", method);
+ EXPECT_EQ(0U, method_offset);
+
+ // Make sure that any data that is cached is still retrievable.
+ ASSERT_TRUE(dex_file->GetMethodInformation(0x104, &method, &method_offset));
+ EXPECT_EQ("Main.<init>", method);
+ EXPECT_EQ(4U, method_offset);
+
+ ASSERT_TRUE(dex_file->GetMethodInformation(0x119, &method, &method_offset));
+ EXPECT_EQ("Main.main", method);
+ EXPECT_EQ(1U, method_offset);
+}
+
+TEST(DexFileTest, get_method_empty) {
+ MemoryFake memory;
+ memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
+ MapInfo info(0x100, 0x10000, 0x200, 0x5, "");
+ std::unique_ptr<DexFile> dex_file(DexFile::Create(0x4000, &memory, &info));
+ ASSERT_TRUE(dex_file != nullptr);
+
+ std::string method;
+ uint64_t method_offset;
+ EXPECT_FALSE(dex_file->GetMethodInformation(0x100000, &method, &method_offset));
+
+ EXPECT_FALSE(dex_file->GetMethodInformation(0x98, &method, &method_offset));
+
+ // Make sure that once the whole dex file has been cached, no problems occur.
+ EXPECT_FALSE(dex_file->GetMethodInformation(0x98, &method, &method_offset));
+
+ // Choose a value that is in the cached map, but not in a valid method.
+ EXPECT_FALSE(dex_file->GetMethodInformation(0x110, &method, &method_offset));
}
} // namespace unwindstack
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 1cfef34..c2487d6 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -332,7 +332,7 @@
data->fd = -1;
return -1;
}
- ALOG_ASSERT((size_t)size < buf_size - 1, data->filename " too large");
+ ALOG_ASSERT((size_t)size < buf_size - 1, "%s too large", data->filename);
buf[size] = 0;
return 0;
diff --git a/trusty/OWNERS b/trusty/OWNERS
index 357b4f4..e807d71 100644
--- a/trusty/OWNERS
+++ b/trusty/OWNERS
@@ -1,3 +1,7 @@
-bohr@google.com
-swillden@google.com
+arve@google.com
dkrahn@google.com
+drewry@google.com
+gmar@google.com
+ncbray@google.com
+rpere@google.com
+swillden@google.com
diff --git a/trusty/libtrusty/tipc-test/tipc_test.c b/trusty/libtrusty/tipc-test/tipc_test.c
index 1fb34c9..d20d4ee 100644
--- a/trusty/libtrusty/tipc-test/tipc_test.c
+++ b/trusty/libtrusty/tipc-test/tipc_test.c
@@ -587,8 +587,15 @@
static int ta2ta_ipc_test(void)
{
+ enum test_message_header {
+ TEST_PASSED = 0,
+ TEST_FAILED = 1,
+ TEST_MESSAGE = 2,
+ };
+
int fd;
- char rx_buf[64];
+ int ret;
+ unsigned char rx_buf[256];
if (!opt_silent) {
printf("%s:\n", __func__);
@@ -601,12 +608,31 @@
return fd;
}
- /* wait for test to complete */
- (void) read(fd, rx_buf, sizeof(rx_buf));
+ /* Wait for tests to complete and read status */
+ while (true) {
+ ret = read(fd, rx_buf, sizeof(rx_buf));
+ if (ret <= 0 || ret >= (int)sizeof(rx_buf)) {
+ fprintf(stderr, "%s: Read failed: %d\n", __func__, ret);
+ tipc_close(fd);
+ return -1;
+ }
+
+ if (rx_buf[0] == TEST_PASSED) {
+ break;
+ } else if (rx_buf[0] == TEST_FAILED) {
+ break;
+ } else if (rx_buf[0] == TEST_MESSAGE) {
+ write(STDOUT_FILENO, rx_buf + 1, ret - 1);
+ } else {
+ fprintf(stderr, "%s: Bad message header: %d\n",
+ __func__, rx_buf[0]);
+ break;
+ }
+ }
tipc_close(fd);
- return 0;
+ return rx_buf[0] == TEST_PASSED ? 0 : -1;
}
typedef struct uuid