Merge "Use generated linker config only"
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index eb737bb..34c64d2 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -26,14 +26,14 @@
],
}
-cc_library {
- // Do not ever allow this library to be vendor_available as a shared library.
- // It does not have a stable interface.
- name: "libfs_mgr",
+cc_defaults {
+ name: "libfs_mgr_defaults",
defaults: ["fs_mgr_defaults"],
- recovery_available: true,
export_include_dirs: ["include"],
include_dirs: ["system/vold"],
+ cflags: [
+ "-D_FILE_OFFSET_BITS=64",
+ ],
srcs: [
"file_wait.cpp",
"fs_mgr.cpp",
@@ -43,6 +43,7 @@
"fs_mgr_overlayfs.cpp",
"fs_mgr_roots.cpp",
"fs_mgr_vendor_overlay.cpp",
+ ":libfiemap_srcs",
],
shared_libs: [
"libbase",
@@ -88,6 +89,42 @@
],
},
},
+ header_libs: [
+ "libfiemap_headers",
+ ],
+ export_header_lib_headers: [
+ "libfiemap_headers",
+ ],
+}
+
+// Two variants of libfs_mgr are provided: libfs_mgr and libfs_mgr_binder.
+// Use libfs_mgr in recovery, first-stage-init, or when libfiemap or overlayfs
+// is not used.
+//
+// Use libfs_mgr_binder when not in recovery/first-stage init, or when overlayfs
+// or libfiemap is needed. In this case, libfiemap will proxy over binder to
+// gsid.
+cc_library {
+ // Do not ever allow this library to be vendor_available as a shared library.
+ // It does not have a stable interface.
+ name: "libfs_mgr",
+ recovery_available: true,
+ defaults: [
+ "libfs_mgr_defaults",
+ ],
+ srcs: [
+ ":libfiemap_passthrough_srcs",
+ ],
+}
+
+cc_library {
+ // Do not ever allow this library to be vendor_available as a shared library.
+ // It does not have a stable interface.
+ name: "libfs_mgr_binder",
+ defaults: [
+ "libfs_mgr_defaults",
+ "libfiemap_binder_defaults",
+ ],
}
cc_library_static {
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 48ce4cd..15c9dfb 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1370,7 +1370,7 @@
Fstab proc_mounts;
if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
LERROR << "Can't read /proc/mounts";
- return -1;
+ return false;
}
// Now proceed with other bind mounts on top of /data.
for (const auto& entry : proc_mounts) {
diff --git a/fs_mgr/libfiemap/Android.bp b/fs_mgr/libfiemap/Android.bp
index 8dbbf4c..fdc1583 100644
--- a/fs_mgr/libfiemap/Android.bp
+++ b/fs_mgr/libfiemap/Android.bp
@@ -20,15 +20,8 @@
export_include_dirs: ["include"],
}
-cc_defaults {
- name: "libfiemap_defaults",
- defaults: ["fs_mgr_defaults"],
- cflags: [
- "-D_FILE_OFFSET_BITS=64",
- "-Wall",
- "-Werror",
- ],
-
+filegroup {
+ name: "libfiemap_srcs",
srcs: [
"fiemap_writer.cpp",
"image_manager.cpp",
@@ -36,55 +29,32 @@
"split_fiemap_writer.cpp",
"utility.cpp",
],
-
- static_libs: [
- "libdm",
- "libext2_uuid",
- "libext4_utils",
- "liblp",
- "libfs_mgr",
- ],
-
- shared_libs: [
- "libbase",
- ],
-
- header_libs: [
- "libfiemap_headers",
- "liblog_headers",
- ],
-
- export_shared_lib_headers: [
- "libbase",
- ],
-
- export_header_lib_headers: [
- "libfiemap_headers",
- ],
}
-// Open up a binder IImageManager interface.
-cc_library_static {
- name: "libfiemap_binder",
- defaults: ["libfiemap_defaults"],
+filegroup {
+ name: "libfiemap_binder_srcs",
srcs: [
"binder.cpp",
],
+}
+
+cc_defaults {
+ name: "libfiemap_binder_defaults",
+ srcs: [":libfiemap_binder_srcs"],
whole_static_libs: [
"gsi_aidl_interface-cpp",
"libgsi",
],
shared_libs: [
"libbinder",
+ "libutils",
],
}
// Open up a passthrough IImageManager interface. Use libfiemap_binder whenever
// possible. This should only be used when binder is not available.
-cc_library_static {
- name: "libfiemap_passthrough",
- defaults: ["libfiemap_defaults"],
- recovery_available: true,
+filegroup {
+ name: "libfiemap_passthrough_srcs",
srcs: [
"passthrough.cpp",
],
@@ -92,10 +62,10 @@
cc_test {
name: "fiemap_writer_test",
- defaults: ["libfiemap_defaults"],
static_libs: [
"libbase",
"libdm",
+ "libfs_mgr",
"liblog",
],
@@ -112,7 +82,6 @@
cc_test {
name: "fiemap_image_test",
- defaults: ["libfiemap_defaults"],
static_libs: [
"libdm",
"libext4_utils",
@@ -120,6 +89,7 @@
"liblp",
],
shared_libs: [
+ "libbase",
"libcrypto",
"libcrypto_utils",
"libcutils",
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index 30d01a6..eadcecc 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -30,7 +30,6 @@
static_libs: [
"libcutils",
"libdm",
- "libfs_mgr",
"libfstab",
"liblp",
"update_metadata-protos",
@@ -93,8 +92,8 @@
"libsnapshot_hal_deps",
],
srcs: [":libsnapshot_sources"],
- whole_static_libs: [
- "libfiemap_binder",
+ static_libs: [
+ "libfs_mgr_binder"
],
}
@@ -103,8 +102,8 @@
defaults: ["libsnapshot_defaults"],
srcs: [":libsnapshot_sources"],
recovery_available: true,
- whole_static_libs: [
- "libfiemap_passthrough",
+ static_libs: [
+ "libfs_mgr",
],
}
@@ -116,8 +115,8 @@
],
srcs: [":libsnapshot_sources"],
recovery_available: true,
- whole_static_libs: [
- "libfiemap_passthrough",
+ static_libs: [
+ "libfs_mgr",
],
}
@@ -144,6 +143,7 @@
"libstorage_literals_headers",
],
static_libs: [
+ "libfs_mgr",
"libgtest",
"libgmock",
],
@@ -170,6 +170,7 @@
"android.hardware.boot@1.1",
"libfs_mgr",
"libgmock",
+ "libgsi",
"liblp",
"libsnapshot",
"libsnapshot_test_helpers",
@@ -189,7 +190,6 @@
static_libs: [
"libdm",
"libext2_uuid",
- "libfiemap_binder",
"libfstab",
"libsnapshot",
],
@@ -200,7 +200,7 @@
"libbinder",
"libbinderthreadstate",
"libext4_utils",
- "libfs_mgr",
+ "libfs_mgr_binder",
"libhidlbase",
"liblog",
"liblp",
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 0f5af14..2da0103 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -606,17 +606,17 @@
std::ostream& operator<<(std::ostream& os, Request request) {
switch (request) {
case Request::LOCK_SHARED:
- return os << "LOCK_SHARED";
+ return os << "Shared";
case Request::LOCK_EXCLUSIVE:
- return os << "LOCK_EXCLUSIVE";
+ return os << "Exclusive";
case Request::UNLOCK:
- return os << "UNLOCK";
+ return os << "Unlock";
case Request::EXIT:
- return os << "EXIT";
+ return os << "Exit";
case Request::UNKNOWN:
[[fallthrough]];
default:
- return os << "UNKNOWN";
+ return os << "Unknown";
}
}
@@ -746,7 +746,7 @@
LockTestParam{Request::LOCK_SHARED, Request::LOCK_EXCLUSIVE}),
[](const testing::TestParamInfo<LockTestP::ParamType>& info) {
std::stringstream ss;
- ss << info.param.first << "_" << info.param.second;
+ ss << info.param.first << info.param.second;
return ss.str();
});
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 5ca1fee..225bc9c 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -834,7 +834,7 @@
}
static void HandleUserspaceReboot() {
- if (!android::sysprop::InitProperties::userspace_reboot_in_progress().value_or(false)) {
+ if (!android::sysprop::InitProperties::is_userspace_reboot_supported().value_or(false)) {
LOG(ERROR) << "Attempted a userspace reboot on a device that doesn't support it";
return;
}
diff --git a/init/service.cpp b/init/service.cpp
index a97935e..0e27ff1 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -325,8 +325,8 @@
LOG(ERROR) << "updatable process '" << name_ << "' exited 4 times "
<< (boot_completed ? "in 4 minutes" : "before boot completed");
// Notifies update_verifier and apexd
- SetProperty("sys.init.updatable_crashing", "1");
SetProperty("sys.init.updatable_crashing_process_name", name_);
+ SetProperty("sys.init.updatable_crashing", "1");
}
}
} else {
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index 7676289..341275d 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -78,10 +78,31 @@
CrcGenerateTable();
Crc64GenerateTable();
- std::vector<uint8_t> src(gnu_debugdata_size_);
- if (!memory_->ReadFully(gnu_debugdata_offset_, src.data(), gnu_debugdata_size_)) {
- gnu_debugdata_offset_ = 0;
- gnu_debugdata_size_ = static_cast<uint64_t>(-1);
+ // Verify the request is not larger than the max size_t value.
+ if (gnu_debugdata_size_ > SIZE_MAX) {
+ return nullptr;
+ }
+ size_t initial_buffer_size;
+ if (__builtin_mul_overflow(5, gnu_debugdata_size_, &initial_buffer_size)) {
+ return nullptr;
+ }
+
+ size_t buffer_increment;
+ if (__builtin_mul_overflow(2, gnu_debugdata_size_, &buffer_increment)) {
+ return nullptr;
+ }
+
+ std::unique_ptr<uint8_t[]> src(new (std::nothrow) uint8_t[gnu_debugdata_size_]);
+ if (src.get() == nullptr) {
+ return nullptr;
+ }
+
+ std::unique_ptr<MemoryBuffer> dst(new MemoryBuffer);
+ if (!dst->Resize(initial_buffer_size)) {
+ return nullptr;
+ }
+
+ if (!memory_->ReadFully(gnu_debugdata_offset_, src.get(), gnu_debugdata_size_)) {
return nullptr;
}
@@ -89,21 +110,23 @@
CXzUnpacker state;
alloc.Alloc = [](ISzAllocPtr, size_t size) { return malloc(size); };
alloc.Free = [](ISzAllocPtr, void* ptr) { return free(ptr); };
-
XzUnpacker_Construct(&state, &alloc);
- std::unique_ptr<MemoryBuffer> dst(new MemoryBuffer);
int return_val;
size_t src_offset = 0;
size_t dst_offset = 0;
ECoderStatus status;
- dst->Resize(5 * gnu_debugdata_size_);
do {
- size_t src_remaining = src.size() - src_offset;
+ size_t src_remaining = gnu_debugdata_size_ - src_offset;
size_t dst_remaining = dst->Size() - dst_offset;
- if (dst_remaining < 2 * gnu_debugdata_size_) {
- dst->Resize(dst->Size() + 2 * gnu_debugdata_size_);
- dst_remaining += 2 * gnu_debugdata_size_;
+ if (dst_remaining < buffer_increment) {
+ size_t new_size;
+ if (__builtin_add_overflow(dst->Size(), buffer_increment, &new_size) ||
+ !dst->Resize(new_size)) {
+ XzUnpacker_Free(&state);
+ return nullptr;
+ }
+ dst_remaining += buffer_increment;
}
return_val = XzUnpacker_Code(&state, dst->GetPtr(dst_offset), &dst_remaining, &src[src_offset],
&src_remaining, true, CODER_FINISH_ANY, &status);
@@ -112,13 +135,13 @@
} while (return_val == SZ_OK && status == CODER_STATUS_NOT_FINISHED);
XzUnpacker_Free(&state);
if (return_val != SZ_OK || !XzUnpacker_IsStreamWasFinished(&state)) {
- gnu_debugdata_offset_ = 0;
- gnu_debugdata_size_ = static_cast<uint64_t>(-1);
return nullptr;
}
// Shrink back down to the exact size.
- dst->Resize(dst_offset);
+ if (!dst->Resize(dst_offset)) {
+ return nullptr;
+ }
return dst.release();
}
diff --git a/libunwindstack/Memory.cpp b/libunwindstack/Memory.cpp
index a66cd5b..8de3d98 100644
--- a/libunwindstack/Memory.cpp
+++ b/libunwindstack/Memory.cpp
@@ -206,12 +206,12 @@
}
size_t MemoryBuffer::Read(uint64_t addr, void* dst, size_t size) {
- if (addr >= raw_.size()) {
+ if (addr >= size_) {
return 0;
}
- size_t bytes_left = raw_.size() - static_cast<size_t>(addr);
- const unsigned char* actual_base = static_cast<const unsigned char*>(raw_.data()) + addr;
+ size_t bytes_left = size_ - static_cast<size_t>(addr);
+ const unsigned char* actual_base = static_cast<const unsigned char*>(raw_) + addr;
size_t actual_len = std::min(bytes_left, size);
memcpy(dst, actual_base, actual_len);
@@ -219,7 +219,7 @@
}
uint8_t* MemoryBuffer::GetPtr(size_t offset) {
- if (offset < raw_.size()) {
+ if (offset < size_) {
return &raw_[offset];
}
return nullptr;
diff --git a/libunwindstack/MemoryBuffer.h b/libunwindstack/MemoryBuffer.h
index 3fe4bbb..a91e59f 100644
--- a/libunwindstack/MemoryBuffer.h
+++ b/libunwindstack/MemoryBuffer.h
@@ -29,18 +29,27 @@
class MemoryBuffer : public Memory {
public:
MemoryBuffer() = default;
- virtual ~MemoryBuffer() = default;
+ virtual ~MemoryBuffer() { free(raw_); }
size_t Read(uint64_t addr, void* dst, size_t size) override;
uint8_t* GetPtr(size_t offset);
- void Resize(size_t size) { raw_.resize(size); }
+ bool Resize(size_t size) {
+ raw_ = reinterpret_cast<uint8_t*>(realloc(raw_, size));
+ if (raw_ == nullptr) {
+ size_ = 0;
+ return false;
+ }
+ size_ = size;
+ return true;
+ }
- uint64_t Size() { return raw_.size(); }
+ uint64_t Size() { return size_; }
private:
- std::vector<uint8_t> raw_;
+ uint8_t* raw_ = nullptr;
+ size_t size_ = 0;
};
} // namespace unwindstack
diff --git a/libunwindstack/tests/ElfFake.h b/libunwindstack/tests/ElfFake.h
index c33908d..fc90dab 100644
--- a/libunwindstack/tests/ElfFake.h
+++ b/libunwindstack/tests/ElfFake.h
@@ -105,6 +105,9 @@
void FakeSetDynamicVaddrStart(uint64_t vaddr) { dynamic_vaddr_start_ = vaddr; }
void FakeSetDynamicVaddrEnd(uint64_t vaddr) { dynamic_vaddr_end_ = vaddr; }
+ void FakeSetGnuDebugdataOffset(uint64_t offset) { gnu_debugdata_offset_ = offset; }
+ void FakeSetGnuDebugdataSize(uint64_t size) { gnu_debugdata_size_ = size; }
+
private:
std::unordered_map<std::string, uint64_t> globals_;
std::string fake_build_id_;
diff --git a/libunwindstack/tests/ElfInterfaceTest.cpp b/libunwindstack/tests/ElfInterfaceTest.cpp
index ea27e3e..3cf90fe 100644
--- a/libunwindstack/tests/ElfInterfaceTest.cpp
+++ b/libunwindstack/tests/ElfInterfaceTest.cpp
@@ -1944,4 +1944,23 @@
CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x5000, 0x1000, -0x4000);
}
+TEST_F(ElfInterfaceTest, huge_gnu_debugdata_size) {
+ ElfInterfaceFake interface(nullptr);
+
+ interface.FakeSetGnuDebugdataOffset(0x1000);
+ interface.FakeSetGnuDebugdataSize(0xffffffffffffffffUL);
+ ASSERT_TRUE(interface.CreateGnuDebugdataMemory() == nullptr);
+
+ interface.FakeSetGnuDebugdataSize(0x4000000000000UL);
+ ASSERT_TRUE(interface.CreateGnuDebugdataMemory() == nullptr);
+
+ // This should exceed the size_t value of the first allocation.
+#if defined(__LP64__)
+ interface.FakeSetGnuDebugdataSize(0x3333333333333334ULL);
+#else
+ interface.FakeSetGnuDebugdataSize(0x33333334);
+#endif
+ ASSERT_TRUE(interface.CreateGnuDebugdataMemory() == nullptr);
+}
+
} // namespace unwindstack
diff --git a/libutils/include/utils/RefBase.h b/libutils/include/utils/RefBase.h
index 42c6efb..89f048d 100644
--- a/libutils/include/utils/RefBase.h
+++ b/libutils/include/utils/RefBase.h
@@ -455,6 +455,7 @@
};
#undef COMPARE_WEAK
+#undef COMPARE_WEAK_FUNCTIONAL
// ---------------------------------------------------------------------------
// No user serviceable parts below here.
diff --git a/libutils/include/utils/StrongPointer.h b/libutils/include/utils/StrongPointer.h
index 07dd3f1..100e507 100644
--- a/libutils/include/utils/StrongPointer.h
+++ b/libutils/include/utils/StrongPointer.h
@@ -134,7 +134,8 @@
void sp_report_race();
void sp_report_stack_pointer();
-#undef COMPARE
+#undef COMPARE_STRONG
+#undef COMPARE_STRONG_FUNCTIONAL
// ---------------------------------------------------------------------------
// No user serviceable parts below here.
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 9cf11a4..fdfcde8 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -978,9 +978,11 @@
on userspace-reboot-requested
# TODO(b/135984674): reset all necessary properties here.
- setprop sys.boot_completed 0
- setprop sys.init.updatable_crashing 0
+ setprop sys.boot_completed ""
+ setprop sys.init.updatable_crashing ""
+ setprop sys.init.updatable_crashing_process_name ""
setprop apexd.status ""
+ setprop sys.user.0.ce_available ""
on userspace-reboot-fs-remount
# Make sure that vold is running.
diff --git a/trusty/storage/proxy/rpmb.c b/trusty/storage/proxy/rpmb.c
index 0bd9e68..03b1099 100644
--- a/trusty/storage/proxy/rpmb.c
+++ b/trusty/storage/proxy/rpmb.c
@@ -16,6 +16,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <scsi/sg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -51,6 +52,50 @@
#define MMC_BLOCK_SIZE 512
+/*
+ * There should be no timeout for security protocol ioctl call, so we choose a
+ * large number for timeout.
+ * 20000 millisecs == 20 seconds
+ */
+#define TIMEOUT 20000
+
+/*
+ * The sg device driver that supports new interface has a major version number of "3".
+ * SG_GET_VERSION_NUM ioctl() will yield a number greater than or 30000.
+ */
+#define RPMB_MIN_SG_VERSION_NUM 30000
+
+/*
+ * CDB format of SECURITY PROTOCOL IN/OUT commands
+ * (JEDEC Standard No. 220D, Page 264)
+ */
+struct sec_proto_cdb {
+ /*
+ * OPERATION CODE = A2h for SECURITY PROTOCOL IN command,
+ * OPERATION CODE = B5h for SECURITY PROTOCOL OUT command.
+ */
+ uint8_t opcode;
+ /* SECURITY PROTOCOL = ECh (JEDEC Universal Flash Storage) */
+ uint8_t sec_proto;
+ /*
+ * The SECURITY PROTOCOL SPECIFIC field specifies the RPMB Protocol ID.
+ * CDB Byte 2 = 00h and CDB Byte 3 = 01h for RPMB Region 0.
+ */
+ uint8_t cdb_byte_2;
+ uint8_t cdb_byte_3;
+ /*
+ * Byte 4 and 5 are reserved.
+ */
+ uint8_t cdb_byte_4;
+ uint8_t cdb_byte_5;
+ /* ALLOCATION/TRANSFER LENGTH in big-endian */
+ uint32_t length;
+ /* Byte 9 is reserved. */
+ uint8_t cdb_byte_10;
+ /* CONTROL = 00h. */
+ uint8_t ctrl;
+} __packed;
+
static int rpmb_fd = -1;
static uint8_t read_buf[4096];
static enum dev_type dev_type = UNKNOWN_RPMB;
@@ -71,6 +116,21 @@
#endif
+static void set_sg_io_hdr(sg_io_hdr_t* io_hdrp, int dxfer_direction, unsigned char cmd_len,
+ unsigned char mx_sb_len, unsigned int dxfer_len, void* dxferp,
+ unsigned char* cmdp, void* sbp) {
+ memset(io_hdrp, 0, sizeof(sg_io_hdr_t));
+ io_hdrp->interface_id = 'S';
+ io_hdrp->dxfer_direction = dxfer_direction;
+ io_hdrp->cmd_len = cmd_len;
+ io_hdrp->mx_sb_len = mx_sb_len;
+ io_hdrp->dxfer_len = dxfer_len;
+ io_hdrp->dxferp = dxferp;
+ io_hdrp->cmdp = cmdp;
+ io_hdrp->sbp = sbp;
+ io_hdrp->timeout = TIMEOUT;
+}
+
static int send_mmc_rpmb_req(int mmc_fd, const struct storage_rpmb_send_req* req) {
struct {
struct mmc_ioc_multi_cmd multi;
@@ -132,6 +192,57 @@
return rc;
}
+static int send_ufs_rpmb_req(int sg_fd, const struct storage_rpmb_send_req* req) {
+ int rc;
+ const uint8_t* write_buf = req->payload;
+ /*
+ * Meaning of member values are stated on the definition of struct sec_proto_cdb.
+ */
+ struct sec_proto_cdb in_cdb = {0xA2, 0xEC, 0x00, 0x01, 0x00, 0x00, 0, 0x00, 0x00};
+ struct sec_proto_cdb out_cdb = {0xB5, 0xEC, 0x00, 0x01, 0x00, 0x00, 0, 0x00, 0x00};
+ unsigned char sense_buffer[32];
+
+ if (req->reliable_write_size) {
+ /* Prepare SECURITY PROTOCOL OUT command. */
+ out_cdb.length = __builtin_bswap32(req->reliable_write_size);
+ sg_io_hdr_t io_hdr;
+ set_sg_io_hdr(&io_hdr, SG_DXFER_TO_DEV, sizeof(out_cdb), sizeof(sense_buffer),
+ req->reliable_write_size, (void*)write_buf, (unsigned char*)&out_cdb,
+ sense_buffer);
+ rc = ioctl(sg_fd, SG_IO, &io_hdr);
+ if (rc < 0) {
+ ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
+ }
+ write_buf += req->reliable_write_size;
+ }
+
+ if (req->write_size) {
+ /* Prepare SECURITY PROTOCOL OUT command. */
+ out_cdb.length = __builtin_bswap32(req->write_size);
+ sg_io_hdr_t io_hdr;
+ set_sg_io_hdr(&io_hdr, SG_DXFER_TO_DEV, sizeof(out_cdb), sizeof(sense_buffer),
+ req->write_size, (void*)write_buf, (unsigned char*)&out_cdb, sense_buffer);
+ rc = ioctl(sg_fd, SG_IO, &io_hdr);
+ if (rc < 0) {
+ ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
+ }
+ write_buf += req->write_size;
+ }
+
+ if (req->read_size) {
+ /* Prepare SECURITY PROTOCOL IN command. */
+ out_cdb.length = __builtin_bswap32(req->read_size);
+ sg_io_hdr_t io_hdr;
+ set_sg_io_hdr(&io_hdr, SG_DXFER_FROM_DEV, sizeof(in_cdb), sizeof(sense_buffer),
+ req->read_size, read_buf, (unsigned char*)&in_cdb, sense_buffer);
+ rc = ioctl(sg_fd, SG_IO, &io_hdr);
+ if (rc < 0) {
+ ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
+ }
+ }
+ return rc;
+}
+
static int send_virt_rpmb_req(int rpmb_fd, void* read_buf, size_t read_size, const void* payload,
size_t payload_size) {
int rc;
@@ -194,6 +305,13 @@
msg->result = STORAGE_ERR_GENERIC;
goto err_response;
}
+ } else if (dev_type == UFS_RPMB) {
+ rc = send_ufs_rpmb_req(rpmb_fd, req);
+ if (rc < 0) {
+ ALOGE("send_ufs_rpmb_req failed: %d, %s\n", rc, strerror(errno));
+ msg->result = STORAGE_ERR_GENERIC;
+ goto err_response;
+ }
} else if ((dev_type == VIRT_RPMB) || (dev_type == SOCK_RPMB)) {
size_t payload_size = req->reliable_write_size + req->write_size;
rc = send_virt_rpmb_req(rpmb_fd, read_buf, req->read_size, req->payload, payload_size);
@@ -233,7 +351,7 @@
}
int rpmb_open(const char* rpmb_devname, enum dev_type open_dev_type) {
- int rc;
+ int rc, sg_version_num;
dev_type = open_dev_type;
if (dev_type != SOCK_RPMB) {
@@ -263,6 +381,16 @@
return rc;
}
}
+
+ /* For UFS, it is prudent to check we hava a sg device by calling an ioctl */
+ if (dev_type == UFS_RPMB) {
+ if ((ioctl(rc, SG_GET_VERSION_NUM, &sg_version_num) < 0) ||
+ (sg_version_num < RPMB_MIN_SG_VERSION_NUM)) {
+ ALOGE("%s is not a sg device, or old sg driver\n", rpmb_devname);
+ return -1;
+ }
+ }
+ rpmb_fd = rc;
return 0;
}
diff --git a/trusty/storage/proxy/rpmb.h b/trusty/storage/proxy/rpmb.h
index 09af3c5..f4e1b51 100644
--- a/trusty/storage/proxy/rpmb.h
+++ b/trusty/storage/proxy/rpmb.h
@@ -18,7 +18,7 @@
#include <stdint.h>
#include <trusty/interface/storage.h>
-enum dev_type { UNKNOWN_RPMB, MMC_RPMB, VIRT_RPMB, SOCK_RPMB };
+enum dev_type { UNKNOWN_RPMB, MMC_RPMB, VIRT_RPMB, UFS_RPMB, SOCK_RPMB };
int rpmb_open(const char* rpmb_devname, enum dev_type dev_type);
int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len);