Merge "libutils: RefBase: extra check for double own"
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 79c3ac7..46190f2 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1683,10 +1683,9 @@
return size;
}
-static void fb_perform_format(
- const std::string& partition, int skip_if_not_supported,
+static void fb_perform_format(const std::string& partition, int skip_if_not_supported,
const std::string& type_override, const std::string& size_override,
- const std::string& initial_dir, const unsigned fs_options) {
+ const unsigned fs_options) {
std::string partition_type, partition_size;
struct fastboot_buffer buf;
@@ -1748,8 +1747,7 @@
eraseBlkSize = fb_get_flash_block_size("erase-block-size");
logicalBlkSize = fb_get_flash_block_size("logical-block-size");
- if (fs_generator_generate(gen, output.path, size, initial_dir,
- eraseBlkSize, logicalBlkSize, fs_options)) {
+ if (fs_generator_generate(gen, output.path, size, eraseBlkSize, logicalBlkSize, fs_options)) {
die("Cannot generate image for %s", partition.c_str());
}
@@ -2091,7 +2089,7 @@
std::string partition = next_arg(&args);
auto format = [&](const std::string& partition) {
- fb_perform_format(partition, 0, type_override, size_override, "", fs_options);
+ fb_perform_format(partition, 0, type_override, size_override, fs_options);
};
do_for_partitions(partition, slot_override, format, true);
} else if (command == "signature") {
@@ -2282,7 +2280,7 @@
}
if (partition_type.empty()) continue;
fb->Erase(partition);
- fb_perform_format(partition, 1, partition_type, "", "", fs_options);
+ fb_perform_format(partition, 1, partition_type, "", fs_options);
}
}
if (wants_set_active) {
diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp
index d268a50..c8d1b59 100644
--- a/fastboot/fs.cpp
+++ b/fastboot/fs.cpp
@@ -111,8 +111,7 @@
}
#endif
-static int generate_ext4_image(const char* fileName, long long partSize,
- const std::string& initial_dir, unsigned eraseBlkSize,
+static int generate_ext4_image(const char* fileName, long long partSize, unsigned eraseBlkSize,
unsigned logicalBlkSize, const unsigned fsOptions) {
static constexpr int block_size = 4096;
const std::string exec_dir = android::base::GetExecutableDirectory();
@@ -163,16 +162,7 @@
if (ret != 0) {
return -1;
}
-
- if (initial_dir.empty()) {
- return 0;
- }
-
- const std::string e2fsdroid_path = exec_dir + "/e2fsdroid";
- std::vector<const char*> e2fsdroid_args = {e2fsdroid_path.c_str(), "-f", initial_dir.c_str(),
- fileName, nullptr};
-
- return exec_cmd(e2fsdroid_args[0], e2fsdroid_args.data(), nullptr);
+ return 0;
}
enum {
@@ -188,8 +178,7 @@
// clang-format on
};
-static int generate_f2fs_image(const char* fileName, long long partSize,
- const std::string& initial_dir, unsigned /* unused */,
+static int generate_f2fs_image(const char* fileName, long long partSize, unsigned /* unused */,
unsigned /* unused */, const unsigned fsOptions) {
const std::string exec_dir = android::base::GetExecutableDirectory();
const std::string mkf2fs_path = exec_dir + "/make_f2fs";
@@ -227,19 +216,6 @@
if (ret != 0) {
return -1;
}
-
- if (initial_dir.empty()) {
- return 0;
- }
-
- const std::string sload_path = exec_dir + "/sload_f2fs";
- std::vector<const char*> sload_args = {sload_path.c_str(), "-S",
- "-f", initial_dir.c_str(), fileName, nullptr};
-
- ret = exec_cmd(sload_args[0], sload_args.data(), nullptr);
- if (ret != 0 && ret != FSCK_ERROR_CORRECTED) {
- return -1;
- }
return 0;
}
@@ -247,8 +223,8 @@
const char* fs_type; //must match what fastboot reports for partition type
//returns 0 or error value
- int (*generate)(const char* fileName, long long partSize, const std::string& initial_dir,
- unsigned eraseBlkSize, unsigned logicalBlkSize, const unsigned fsOptions);
+ int (*generate)(const char* fileName, long long partSize, unsigned eraseBlkSize,
+ unsigned logicalBlkSize, const unsigned fsOptions);
} generators[] = {
{ "ext4", generate_ext4_image},
@@ -265,7 +241,7 @@
}
int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize,
- const std::string& initial_dir, unsigned eraseBlkSize,
- unsigned logicalBlkSize, const unsigned fsOptions) {
- return gen->generate(fileName, partSize, initial_dir, eraseBlkSize, logicalBlkSize, fsOptions);
+ unsigned eraseBlkSize, unsigned logicalBlkSize,
+ const unsigned fsOptions) {
+ return gen->generate(fileName, partSize, eraseBlkSize, logicalBlkSize, fsOptions);
}
diff --git a/fastboot/fs.h b/fastboot/fs.h
index f832938..5ae473b 100644
--- a/fastboot/fs.h
+++ b/fastboot/fs.h
@@ -13,5 +13,5 @@
const struct fs_generator* fs_get_generator(const std::string& fs_type);
int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize,
- const std::string& initial_dir, unsigned eraseBlkSize = 0,
- unsigned logicalBlkSize = 0, unsigned fsOptions = 0);
+ unsigned eraseBlkSize = 0, unsigned logicalBlkSize = 0,
+ unsigned fsOptions = 0);
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index f1071b0..43961da 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -439,34 +439,6 @@
return fstab_result;
}
-// Return the path to the fstab file. There may be multiple fstab files; the
-// one that is returned will be the first that exists of fstab.<fstab_suffix>,
-// fstab.<hardware>, and fstab.<hardware.platform>. The fstab is searched for
-// in /odm/etc/ and /vendor/etc/, as well as in the locations where it may be in
-// the first stage ramdisk during early boot. Previously, the first stage
-// ramdisk's copy of the fstab had to be located in the root directory, but now
-// the system/etc directory is supported too and is the preferred location.
-std::string GetFstabPath() {
- for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
- std::string suffix;
-
- if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
-
- for (const char* prefix : {// late-boot/post-boot locations
- "/odm/etc/fstab.", "/vendor/etc/fstab.",
- // early boot locations
- "/system/etc/fstab.", "/first_stage_ramdisk/system/etc/fstab.",
- "/fstab.", "/first_stage_ramdisk/fstab."}) {
- std::string fstab_path = prefix + suffix;
- if (access(fstab_path.c_str(), F_OK) == 0) {
- return fstab_path;
- }
- }
- }
-
- return "";
-}
-
/* Extracts <device>s from the by-name symlinks specified in a fstab:
* /dev/block/<type>/<device>/by-name/<partition>
*
@@ -526,6 +498,34 @@
} // namespace
+// Return the path to the fstab file. There may be multiple fstab files; the
+// one that is returned will be the first that exists of fstab.<fstab_suffix>,
+// fstab.<hardware>, and fstab.<hardware.platform>. The fstab is searched for
+// in /odm/etc/ and /vendor/etc/, as well as in the locations where it may be in
+// the first stage ramdisk during early boot. Previously, the first stage
+// ramdisk's copy of the fstab had to be located in the root directory, but now
+// the system/etc directory is supported too and is the preferred location.
+std::string GetFstabPath() {
+ for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
+ std::string suffix;
+
+ if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
+
+ for (const char* prefix : {// late-boot/post-boot locations
+ "/odm/etc/fstab.", "/vendor/etc/fstab.",
+ // early boot locations
+ "/system/etc/fstab.", "/first_stage_ramdisk/system/etc/fstab.",
+ "/fstab.", "/first_stage_ramdisk/fstab."}) {
+ std::string fstab_path = prefix + suffix;
+ if (access(fstab_path.c_str(), F_OK) == 0) {
+ return fstab_path;
+ }
+ }
+ }
+
+ return "";
+}
+
bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out) {
const int expected_fields = proc_mounts ? 4 : 5;
@@ -804,7 +804,7 @@
std::string default_fstab_path;
// Use different fstab paths for normal boot and recovery boot, respectively
- if (access("/system/bin/recovery", F_OK) == 0) {
+ if ((access("/sbin/recovery", F_OK) == 0) || (access("/system/bin/recovery", F_OK) == 0)) {
default_fstab_path = "/etc/recovery.fstab";
} else { // normal boot
default_fstab_path = GetFstabPath();
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 82b5275..07eaf58 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -642,6 +642,10 @@
if (ret) {
PERROR << "__mount(target=" << mount_point
<< ",flag=" << (shared_flag ? "MS_SHARED" : "MS_PRIVATE") << ")=" << ret;
+ // If "/system" doesn't look like a mountpoint, retry with "/".
+ if (errno == EINVAL && mount_point == "/system") {
+ return fs_mgr_overlayfs_set_shared_mount("/", shared_flag);
+ }
return false;
}
return true;
@@ -1140,7 +1144,13 @@
return 0;
}
- return std::min(super_info.size, (uint64_t(s.f_frsize) * s.f_bfree) / 2);
+ auto ideal_size = std::min(super_info.size, (uint64_t(s.f_frsize) * s.f_bfree) / 2);
+
+ // Align up to the filesystem block size.
+ if (auto remainder = ideal_size % s.f_bsize; remainder > 0) {
+ ideal_size += s.f_bsize - remainder;
+ }
+ return ideal_size;
}
static bool CreateScratchOnData(std::string* scratch_device, bool* partition_exists, bool* change) {
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 8f200a8..689d18b 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -95,6 +95,8 @@
// Exported for testability. Regular users should use ReadFstabFromFile().
bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out);
+// Exported for testability. Regular users should use ReadDefaultFstab().
+std::string GetFstabPath();
bool ReadFstabFromFile(const std::string& path, Fstab* fstab);
bool ReadFstabFromDt(Fstab* fstab, bool verbose = true);
diff --git a/fs_mgr/libfiemap/image_test.cpp b/fs_mgr/libfiemap/image_test.cpp
index 7472949..fb104b7 100644
--- a/fs_mgr/libfiemap/image_test.cpp
+++ b/fs_mgr/libfiemap/image_test.cpp
@@ -14,11 +14,13 @@
// limitations under the License.
//
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/vfs.h>
#include <chrono>
#include <iostream>
@@ -26,12 +28,14 @@
#include <android-base/file.h>
#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <ext4_utils/ext4_utils.h>
#include <fs_mgr/file_wait.h>
#include <gtest/gtest.h>
#include <libdm/dm.h>
+#include <libdm/loop_control.h>
#include <libfiemap/image_manager.h>
#include "utility.h"
@@ -46,7 +50,7 @@
using android::fs_mgr::WaitForFile;
static std::string gDataPath;
-static std::string gDataMountPath;
+static std::string gTestDir;
static constexpr char kMetadataPath[] = "/metadata/gsi/test";
static constexpr uint64_t kTestImageSize = 1024 * 1024;
@@ -178,6 +182,119 @@
INSTANTIATE_TEST_SUITE_P(IsSubdirTest, IsSubdirTest, ::testing::ValuesIn(IsSubdirTestValues()));
+// This allows test cases for filesystems with larger than 4KiB alignment.
+// It creates a loop device, formats it with a FAT filesystem, and then
+// creates an ImageManager so backing images can be created on that filesystem.
+class VfatTest : public ::testing::Test {
+ protected:
+ // 64MB Filesystem and 32k block size by default
+ static constexpr uint64_t kBlockSize = 32768;
+ static constexpr uint64_t kFilesystemSize = 64 * 1024 * 1024;
+
+ void SetUp() override {
+ const ::testing::TestInfo* tinfo = ::testing::UnitTest::GetInstance()->current_test_info();
+ base_name_ = tinfo->name();
+
+ fs_path_ = gTestDir + "/vfat.img";
+ uint64_t count = kFilesystemSize / kBlockSize;
+ std::string dd_cmd =
+ ::android::base::StringPrintf("/system/bin/dd if=/dev/zero of=%s bs=%" PRIu64
+ " count=%" PRIu64 " > /dev/null 2>&1",
+ fs_path_.c_str(), kBlockSize, count);
+ // create mount point
+ mntpoint_ = std::string(getenv("TMPDIR")) + "/fiemap_mnt";
+ if (mkdir(mntpoint_.c_str(), S_IRWXU) < 0) {
+ ASSERT_EQ(errno, EEXIST) << strerror(errno);
+ }
+
+ // create file for the file system
+ int ret = system(dd_cmd.c_str());
+ ASSERT_EQ(ret, 0);
+
+ // Get and attach a loop device to the filesystem we created
+ loop_device_.emplace(fs_path_, 10s);
+ ASSERT_TRUE(loop_device_->valid());
+
+ // create file system
+ uint64_t sectors = kFilesystemSize / 512;
+ std::string mkfs_cmd =
+ ::android::base::StringPrintf("/system/bin/newfs_msdos -A -O Android -s %" PRIu64
+ " -b %" PRIu64 " %s > /dev/null 2>&1",
+ sectors, kBlockSize, loop_device_->device().c_str());
+ ret = system(mkfs_cmd.c_str());
+ ASSERT_EQ(ret, 0);
+
+ // Create a wrapping DM device to prevent gsid taking the loopback path.
+ auto& dm = DeviceMapper::Instance();
+ DmTable table;
+ table.Emplace<DmTargetLinear>(0, kFilesystemSize / 512, loop_device_->device(), 0);
+
+ dm_name_ = android::base::Basename(loop_device_->device()) + "-wrapper";
+ ASSERT_TRUE(dm.CreateDevice(dm_name_, table, &dm_path_, 10s));
+
+ // mount the file system
+ ASSERT_EQ(mount(dm_path_.c_str(), mntpoint_.c_str(), "vfat", 0, nullptr), 0)
+ << strerror(errno);
+ }
+
+ void TearDown() override {
+ // Clear up anything backed on the temporary FS.
+ if (manager_) {
+ manager_->UnmapImageIfExists(base_name_);
+ manager_->DeleteBackingImage(base_name_);
+ }
+
+ // Unmount temporary FS.
+ if (umount(mntpoint_.c_str()) < 0) {
+ ASSERT_EQ(errno, EINVAL) << strerror(errno);
+ }
+
+ // Destroy the dm wrapper.
+ auto& dm = DeviceMapper::Instance();
+ ASSERT_TRUE(dm.DeleteDeviceIfExists(dm_name_));
+
+ // Destroy the loop device.
+ loop_device_ = {};
+
+ // Destroy the temporary FS.
+ if (rmdir(mntpoint_.c_str()) < 0) {
+ ASSERT_EQ(errno, ENOENT) << strerror(errno);
+ }
+ if (unlink(fs_path_.c_str()) < 0) {
+ ASSERT_EQ(errno, ENOENT) << strerror(errno);
+ }
+ }
+
+ std::string base_name_;
+ std::string mntpoint_;
+ std::string fs_path_;
+ std::optional<LoopDevice> loop_device_;
+ std::string dm_name_;
+ std::string dm_path_;
+ std::unique_ptr<ImageManager> manager_;
+};
+
+// The actual size of the block device should be the requested size. For
+// example, a 16KB image should be mapped as a 16KB device, even if the
+// underlying filesystem requires 32KB to be fallocated.
+TEST_F(VfatTest, DeviceIsRequestedSize) {
+ manager_ = ImageManager::Open(kMetadataPath, mntpoint_);
+ ASSERT_NE(manager_, nullptr);
+
+ manager_->set_partition_opener(std::make_unique<TestPartitionOpener>());
+
+ // Create something not aligned to the backing fs block size.
+ constexpr uint64_t kTestSize = (kBlockSize * 64) - (kBlockSize / 2);
+ ASSERT_TRUE(manager_->CreateBackingImage(base_name_, kTestSize, false, nullptr));
+
+ std::string path;
+ ASSERT_TRUE(manager_->MapImageDevice(base_name_, 10s, &path));
+
+ unique_fd fd(open(path.c_str(), O_RDONLY | O_CLOEXEC));
+ ASSERT_GE(fd, 0);
+ ASSERT_EQ(get_block_device_size(fd.get()), kTestSize);
+}
+
} // namespace
bool Mkdir(const std::string& path) {
@@ -194,13 +311,27 @@
if (argc >= 2) {
gDataPath = argv[1];
} else {
- gDataPath = "/data/gsi/test";
+ gDataPath = "/data/local/tmp";
}
- gDataMountPath = gDataPath + "/mnt"s;
- if (!Mkdir(gDataPath) || !Mkdir(kMetadataPath) || !Mkdir(gDataMountPath) ||
- !Mkdir(kMetadataPath + "/mnt"s)) {
+ if (!Mkdir(gDataPath) || !Mkdir(kMetadataPath) || !Mkdir(kMetadataPath + "/mnt"s)) {
return 1;
}
- return RUN_ALL_TESTS();
+
+ std::string tempdir = gDataPath + "/XXXXXX";
+ if (!mkdtemp(tempdir.data())) {
+ std::cerr << "unable to create tempdir on " << tempdir << "\n";
+ exit(EXIT_FAILURE);
+ }
+ if (!android::base::Realpath(tempdir, &gTestDir)) {
+ std::cerr << "unable to find realpath for " << tempdir;
+ exit(EXIT_FAILURE);
+ }
+
+ auto rv = RUN_ALL_TESTS();
+
+ std::string cmd = "rm -rf " + gTestDir;
+ system(cmd.c_str());
+
+ return rv;
}
diff --git a/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h b/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
index be18b42..762aebb 100644
--- a/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
+++ b/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
@@ -196,9 +196,10 @@
// Expect space of |path| is multiple of 4K.
bool WriteRandomData(const std::string& path, std::optional<size_t> expect_size = std::nullopt,
std::string* hash = nullptr);
-bool WriteRandomData(ICowWriter* writer, std::string* hash = nullptr);
std::string HashSnapshot(ISnapshotWriter* writer);
+std::string ToHexString(const uint8_t* buf, size_t len);
+
std::optional<std::string> GetHash(const std::string& path);
// Add partitions and groups described by |manifest|.
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index b889fd4..f0e91de 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -40,6 +40,7 @@
#include <libdm/dm.h>
#include <libfiemap/image_manager.h>
#include <liblp/builder.h>
+#include <openssl/sha.h>
#include <storage_literals/storage_literals.h>
#include <android/snapshot/snapshot.pb.h>
@@ -1040,14 +1041,25 @@
}
}
- AssertionResult WriteSnapshotAndHash(const std::string& name) {
+ AssertionResult WriteSnapshots() {
+ for (const auto& partition : {sys_, vnd_, prd_}) {
+ auto res = WriteSnapshotAndHash(partition);
+ if (!res) {
+ return res;
+ }
+ }
+ return AssertionSuccess();
+ }
+
+ AssertionResult WriteSnapshotAndHash(PartitionUpdate* partition) {
+ std::string name = partition->partition_name() + "_b";
if (ShouldUseCompression()) {
std::unique_ptr<ISnapshotWriter> writer;
auto res = MapUpdateSnapshot(name, &writer);
if (!res) {
return res;
}
- if (!WriteRandomData(writer.get(), &hashes_[name])) {
+ if (!WriteRandomSnapshotData(writer.get(), &hashes_[name])) {
return AssertionFailure() << "Unable to write random data to snapshot " << name;
}
if (!writer->Finalize()) {
@@ -1071,6 +1083,42 @@
<< ", hash: " << hashes_[name];
}
+ bool WriteRandomSnapshotData(ICowWriter* writer, std::string* hash) {
+ unique_fd rand(open("/dev/urandom", O_RDONLY));
+ if (rand < 0) {
+ PLOG(ERROR) << "open /dev/urandom";
+ return false;
+ }
+
+ SHA256_CTX ctx;
+ SHA256_Init(&ctx);
+
+ if (!writer->options().max_blocks) {
+ LOG(ERROR) << "CowWriter must specify maximum number of blocks";
+ return false;
+ }
+ const auto num_blocks = writer->options().max_blocks.value();
+
+ const auto block_size = writer->options().block_size;
+ std::string block(block_size, '\0');
+ for (uint64_t i = 0; i < num_blocks; i++) {
+ if (!ReadFully(rand, block.data(), block.size())) {
+ PLOG(ERROR) << "read /dev/urandom";
+ return false;
+ }
+ if (!writer->AddRawBlocks(i, block.data(), block.size())) {
+ LOG(ERROR) << "Failed to add raw block " << i;
+ return false;
+ }
+ SHA256_Update(&ctx, block.data(), block.size());
+ }
+
+ uint8_t out[32];
+ SHA256_Final(out, &ctx);
+ *hash = ToHexString(out, sizeof(out));
+ return true;
+ }
+
// Generate a snapshot that moves all the upper blocks down to the start.
// It doesn't really matter the order, we just want copies that reference
// blocks that won't exist if the partition shrinks.
@@ -1179,9 +1227,7 @@
ASSERT_EQ(nullptr, tgt->FindPartition("prd_b-cow"));
// Write some data to target partitions.
- for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
- ASSERT_TRUE(WriteSnapshotAndHash(name));
- }
+ ASSERT_TRUE(WriteSnapshots());
// Assert that source partitions aren't affected.
for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
@@ -1245,9 +1291,7 @@
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
// Write some data to target partitions.
- for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
- ASSERT_TRUE(WriteSnapshotAndHash(name));
- }
+ ASSERT_TRUE(WriteSnapshots());
std::vector<PartitionUpdate*> partitions = {sys_, vnd_, prd_};
for (auto* partition : partitions) {
@@ -1311,8 +1355,8 @@
ASSERT_EQ(status.old_partition_size(), 3145728);
}
- ASSERT_TRUE(WriteSnapshotAndHash("sys_b"));
- ASSERT_TRUE(WriteSnapshotAndHash("vnd_b"));
+ ASSERT_TRUE(WriteSnapshotAndHash(sys_));
+ ASSERT_TRUE(WriteSnapshotAndHash(vnd_));
ASSERT_TRUE(ShiftAllSnapshotBlocks("prd_b", old_prd_size));
sync();
@@ -1415,8 +1459,8 @@
ASSERT_TRUE(sm->BeginUpdate());
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
- ASSERT_TRUE(WriteSnapshotAndHash("sys_b"));
- ASSERT_TRUE(WriteSnapshotAndHash("vnd_b"));
+ ASSERT_TRUE(WriteSnapshotAndHash(sys_));
+ ASSERT_TRUE(WriteSnapshotAndHash(vnd_));
ASSERT_TRUE(ShiftAllSnapshotBlocks("prd_b", old_prd_size));
sync();
@@ -1577,9 +1621,7 @@
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
// Write some data to target partitions.
- for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
- ASSERT_TRUE(WriteSnapshotAndHash(name));
- }
+ ASSERT_TRUE(WriteSnapshots());
// Assert that source partitions aren't affected.
for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
@@ -1738,9 +1780,7 @@
ASSERT_FALSE(image_manager_->BackingImageExists("prd_b-cow-img"));
// Write some data to target partitions.
- for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
- ASSERT_TRUE(WriteSnapshotAndHash(name));
- }
+ ASSERT_TRUE(WriteSnapshots());
// Assert that source partitions aren't affected.
for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
@@ -2012,9 +2052,7 @@
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
// Write some data to target partitions.
- for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
- ASSERT_TRUE(WriteSnapshotAndHash(name)) << name;
- }
+ ASSERT_TRUE(WriteSnapshots());
ASSERT_TRUE(sm->FinishedSnapshotWrites(true /* wipe */));
@@ -2054,9 +2092,7 @@
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
// Write some data to target partitions.
- for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
- ASSERT_TRUE(WriteSnapshotAndHash(name)) << name;
- }
+ ASSERT_TRUE(WriteSnapshots());
// Create a stale snapshot that should not exist.
{
@@ -2139,7 +2175,7 @@
// Map and write some data to target partition.
ASSERT_TRUE(MapUpdateSnapshots({"vnd_b", "prd_b"}));
- ASSERT_TRUE(WriteSnapshotAndHash("sys_b"));
+ ASSERT_TRUE(WriteSnapshotAndHash(sys_));
// Finish update.
ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
@@ -2175,7 +2211,7 @@
// Map and write some data to target partitions.
ASSERT_TRUE(MapUpdateSnapshots({"vnd_b", "prd_b"}));
- ASSERT_TRUE(WriteSnapshotAndHash("sys_b"));
+ ASSERT_TRUE(WriteSnapshotAndHash(sys_));
std::vector<android::dm::DeviceMapper::TargetInfo> table;
ASSERT_TRUE(DeviceMapper::Instance().GetTableStatus("sys_b", &table));
@@ -2235,8 +2271,8 @@
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
// Write some data to target partitions.
- for (const auto& name : {"sys_b", "vnd_b", "prd_b", "dlkm_b"}) {
- ASSERT_TRUE(WriteSnapshotAndHash(name));
+ for (const auto& partition : {sys_, vnd_, prd_, dlkm}) {
+ ASSERT_TRUE(WriteSnapshotAndHash(partition));
}
// Assert that source partitions aren't affected.
@@ -2360,9 +2396,7 @@
// Execute the update.
ASSERT_TRUE(sm->BeginUpdate());
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
- for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
- ASSERT_TRUE(WriteSnapshotAndHash(name));
- }
+ ASSERT_TRUE(WriteSnapshots());
ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
ASSERT_TRUE(sm->MapAllSnapshots(10s));
@@ -2412,13 +2446,6 @@
// fit in super, but not |prd|.
constexpr uint64_t partition_size = 3788_KiB;
SetSize(sys_, partition_size);
- SetSize(vnd_, partition_size);
- SetSize(prd_, 18_MiB);
-
- // Make sure |prd| does not fit in super at all. On VABC, this means we
- // fake an extra large COW for |vnd| to fill up super.
- vnd_->set_estimate_cow_size(30_MiB);
- prd_->set_estimate_cow_size(30_MiB);
AddOperationForPartitions();
@@ -2430,23 +2457,7 @@
GTEST_SKIP() << "Test does not apply to userspace snapshots";
}
- // Test that partitions prioritize using space in super.
- auto tgt = MetadataBuilder::New(*opener_, "super", 1);
- ASSERT_NE(tgt, nullptr);
- ASSERT_NE(nullptr, tgt->FindPartition("sys_b-cow"));
- ASSERT_NE(nullptr, tgt->FindPartition("vnd_b-cow"));
- ASSERT_EQ(nullptr, tgt->FindPartition("prd_b-cow"));
-
- // Write some data to target partitions.
- for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
- ASSERT_TRUE(WriteSnapshotAndHash(name));
- }
-
- // Assert that source partitions aren't affected.
- for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
- ASSERT_TRUE(IsPartitionUnchanged(name));
- }
-
+ ASSERT_TRUE(WriteSnapshots());
ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
ASSERT_TRUE(UnmapAll());
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
index 17f3c4f..63f47d6 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
@@ -71,16 +71,16 @@
}
bool Worker::MergeReplaceZeroOps() {
- // Flush every 8192 ops. Since all ops are independent and there is no
+ // Flush after merging 2MB. Since all ops are independent and there is no
// dependency between COW ops, we will flush the data and the number
- // of ops merged in COW file for every 8192 ops. If there is a crash,
- // we will end up replaying some of the COW ops which were already merged.
- // That is ok.
+ // of ops merged in COW block device. If there is a crash, we will
+ // end up replaying some of the COW ops which were already merged. That is
+ // ok.
//
- // Why 8192 ops ? Increasing this may improve merge time 3-4 seconds but
- // we need to make sure that we checkpoint; 8k ops seems optimal. In-case
- // if there is a crash merge should always make forward progress.
- int total_ops_merged_per_commit = (PAYLOAD_BUFFER_SZ / BLOCK_SZ) * 32;
+ // Although increasing this greater than 2MB may help in improving merge
+ // times; however, on devices with low memory, this can be problematic
+ // when there are multiple merge threads in parallel.
+ int total_ops_merged_per_commit = (PAYLOAD_BUFFER_SZ / BLOCK_SZ) * 2;
int num_ops_merged = 0;
SNAP_LOG(INFO) << "MergeReplaceZeroOps started....";
diff --git a/fs_mgr/libsnapshot/test_helpers.cpp b/fs_mgr/libsnapshot/test_helpers.cpp
index 71fe124..3e889a0 100644
--- a/fs_mgr/libsnapshot/test_helpers.cpp
+++ b/fs_mgr/libsnapshot/test_helpers.cpp
@@ -128,48 +128,6 @@
return true;
}
-bool WriteRandomData(ICowWriter* writer, std::string* hash) {
- unique_fd rand(open("/dev/urandom", O_RDONLY));
- if (rand < 0) {
- PLOG(ERROR) << "open /dev/urandom";
- return false;
- }
-
- SHA256_CTX ctx;
- if (hash) {
- SHA256_Init(&ctx);
- }
-
- if (!writer->options().max_blocks) {
- LOG(ERROR) << "CowWriter must specify maximum number of blocks";
- return false;
- }
- uint64_t num_blocks = writer->options().max_blocks.value();
-
- size_t block_size = writer->options().block_size;
- std::string block(block_size, '\0');
- for (uint64_t i = 0; i < num_blocks; i++) {
- if (!ReadFully(rand, block.data(), block.size())) {
- PLOG(ERROR) << "read /dev/urandom";
- return false;
- }
- if (!writer->AddRawBlocks(i, block.data(), block.size())) {
- LOG(ERROR) << "Failed to add raw block " << i;
- return false;
- }
- if (hash) {
- SHA256_Update(&ctx, block.data(), block.size());
- }
- }
-
- if (hash) {
- uint8_t out[32];
- SHA256_Final(out, &ctx);
- *hash = ToHexString(out, sizeof(out));
- }
- return true;
-}
-
std::string HashSnapshot(ISnapshotWriter* writer) {
auto reader = writer->OpenReader();
if (!reader) {
diff --git a/fs_mgr/tests/vts_fs_test.cpp b/fs_mgr/tests/vts_fs_test.cpp
index ae8e459..b8b34e2 100644
--- a/fs_mgr/tests/vts_fs_test.cpp
+++ b/fs_mgr/tests/vts_fs_test.cpp
@@ -23,6 +23,9 @@
#include <gtest/gtest.h>
#include <libdm/dm.h>
+using testing::Contains;
+using testing::Not;
+
static int GetVsrLevel() {
return android::base::GetIntProperty("ro.vendor.api_level", -1);
}
@@ -117,3 +120,30 @@
android::fs_mgr::Fstab fstab;
EXPECT_FALSE(android::fs_mgr::ReadFstabFromDt(&fstab, false));
}
+
+TEST(fs, NoLegacyVerifiedBoot) {
+ if (GetVsrLevel() < __ANDROID_API_T__) {
+ GTEST_SKIP();
+ }
+
+ const auto& default_fstab_path = android::fs_mgr::GetFstabPath();
+ EXPECT_FALSE(default_fstab_path.empty());
+
+ std::string fstab_str;
+ EXPECT_TRUE(android::base::ReadFileToString(default_fstab_path, &fstab_str,
+ /* follow_symlinks = */ true));
+
+ for (const auto& line : android::base::Split(fstab_str, "\n")) {
+ auto fields = android::base::Tokenize(line, " \t");
+ // Ignores empty lines and comments.
+ if (fields.empty() || android::base::StartsWith(fields.front(), '#')) {
+ continue;
+ }
+ // Each line in a fstab should have at least five entries.
+ // <src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
+ ASSERT_GE(fields.size(), 5);
+ EXPECT_THAT(android::base::Split(fields[4], ","), Not(Contains("verify")))
+ << "AVB 1.0 isn't supported now, but the 'verify' flag is found:\n"
+ << " " << line;
+ }
+}
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index ff95487..07ce458 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -518,12 +518,6 @@
SwitchRoot("/system");
- // Make /system a mountpoint so that adb-remount can move submounts under /system.
- if (access("/system", F_OK) == 0 &&
- mount("/system", "/system", nullptr, MS_BIND, nullptr) != 0) {
- PLOG(WARNING) << "Failed to bind mount /system for overlayfs";
- }
-
return true;
}
diff --git a/init/init.cpp b/init/init.cpp
index 535033d..5f516b7 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -347,8 +347,8 @@
}
#endif // RECOVERY
parser.AddSectionParser("service",
- std::make_unique<ServiceParser>(&service_list, subcontext, std::nullopt,
- /*from_apex=*/true));
+ std::make_unique<ServiceParser>(&service_list, subcontext,
+ std::nullopt));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, subcontext));
return parser;
diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp
index bce1cc3..fead371 100644
--- a/init/mount_namespace.cpp
+++ b/init/mount_namespace.cpp
@@ -190,15 +190,33 @@
return success;
}
+// Switch the mount namespace of the current process from bootstrap to default OR from default to
+// bootstrap. If the current mount namespace is neither bootstrap nor default, keep it that way.
Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace) {
if (IsRecoveryMode() || !IsApexUpdatable()) {
// we don't have multiple namespaces in recovery mode or if apex is not updatable
return {};
}
- const auto& ns_id = target_mount_namespace == NS_BOOTSTRAP ? bootstrap_ns_id : default_ns_id;
+
+ const std::string current_namespace_id = GetMountNamespaceId();
+ MountNamespace current_mount_namespace;
+ if (current_namespace_id == bootstrap_ns_id) {
+ current_mount_namespace = NS_BOOTSTRAP;
+ } else if (current_namespace_id == default_ns_id) {
+ current_mount_namespace = NS_DEFAULT;
+ } else {
+ // services with `namespace mnt` start in its own mount namespace. So we need to keep it.
+ return {};
+ }
+
+ // We're already in the target mount namespace.
+ if (current_mount_namespace == target_mount_namespace) {
+ return {};
+ }
+
const auto& ns_fd = target_mount_namespace == NS_BOOTSTRAP ? bootstrap_ns_fd : default_ns_fd;
const auto& ns_name = target_mount_namespace == NS_BOOTSTRAP ? "bootstrap" : "default";
- if (ns_id != GetMountNamespaceId() && ns_fd.get() != -1) {
+ if (ns_fd.get() != -1) {
if (setns(ns_fd.get(), CLONE_NEWNS) == -1) {
return ErrnoError() << "Failed to switch to " << ns_name << " mount namespace.";
}
diff --git a/init/service.cpp b/init/service.cpp
index 8c4ee93..730b6b6 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -130,13 +130,13 @@
std::chrono::time_point<std::chrono::steady_clock> Service::exec_service_started_;
Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
- const std::vector<std::string>& args, bool from_apex)
- : Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, args, from_apex) {}
+ const std::string& filename, const std::vector<std::string>& args)
+ : Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, filename, args) {}
Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
const std::vector<gid_t>& supp_gids, int namespace_flags,
const std::string& seclabel, Subcontext* subcontext_for_restart_commands,
- const std::vector<std::string>& args, bool from_apex)
+ const std::string& filename, const std::vector<std::string>& args)
: name_(name),
classnames_({"default"}),
flags_(flags),
@@ -156,7 +156,7 @@
oom_score_adjust_(DEFAULT_OOM_SCORE_ADJUST),
start_order_(0),
args_(args),
- from_apex_(from_apex) {}
+ filename_(filename) {}
void Service::NotifyStateChange(const std::string& new_state) const {
if ((flags_ & SVC_TEMPORARY) != 0) {
@@ -860,7 +860,7 @@
}
return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, namespace_flags, seclabel,
- nullptr, str_args, false);
+ nullptr, /*filename=*/"", str_args);
}
// This is used for snapuserd_proxy, which hands off a socket to snapuserd. It's
diff --git a/init/service.h b/init/service.h
index 4adbaa2..f7f32d9 100644
--- a/init/service.h
+++ b/init/service.h
@@ -66,12 +66,12 @@
public:
Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
- const std::vector<std::string>& args, bool from_apex = false);
+ const std::string& filename, const std::vector<std::string>& args);
Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
const std::vector<gid_t>& supp_gids, int namespace_flags, const std::string& seclabel,
- Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args,
- bool from_apex = false);
+ Subcontext* subcontext_for_restart_commands, const std::string& filename,
+ const std::vector<std::string>& args);
static Result<std::unique_ptr<Service>> MakeTemporaryOneshotService(
const std::vector<std::string>& args);
@@ -133,7 +133,7 @@
const std::vector<std::string>& args() const { return args_; }
bool is_updatable() const { return updatable_; }
bool is_post_data() const { return post_data_; }
- bool is_from_apex() const { return from_apex_; }
+ bool is_from_apex() const { return base::StartsWith(filename_, "/apex/"); }
void set_oneshot(bool value) {
if (value) {
flags_ |= SVC_ONESHOT;
@@ -225,7 +225,7 @@
std::optional<std::string> on_failure_reboot_target_;
- bool from_apex_ = false;
+ std::string filename_;
};
} // namespace init
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index 9e914ee..32c57c4 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -647,7 +647,7 @@
}
}
- service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args, from_apex_);
+ service_ = std::make_unique<Service>(name, restart_action_subcontext, filename, str_args);
return {};
}
diff --git a/init/service_parser.h b/init/service_parser.h
index 0fd2da5..54503dd 100644
--- a/init/service_parser.h
+++ b/init/service_parser.h
@@ -31,13 +31,11 @@
public:
ServiceParser(
ServiceList* service_list, Subcontext* subcontext,
- const std::optional<InterfaceInheritanceHierarchyMap>& interface_inheritance_hierarchy,
- bool from_apex = false)
+ const std::optional<InterfaceInheritanceHierarchyMap>& interface_inheritance_hierarchy)
: service_list_(service_list),
subcontext_(subcontext),
interface_inheritance_hierarchy_(interface_inheritance_hierarchy),
- service_(nullptr),
- from_apex_(from_apex) {}
+ service_(nullptr) {}
Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
int line) override;
Result<void> ParseLineSection(std::vector<std::string>&& args, int line) override;
@@ -92,7 +90,6 @@
std::optional<InterfaceInheritanceHierarchyMap> interface_inheritance_hierarchy_;
std::unique_ptr<Service> service_;
std::string filename_;
- bool from_apex_ = false;
};
} // namespace init
diff --git a/init/service_test.cpp b/init/service_test.cpp
index 22ee844..87a2ce5 100644
--- a/init/service_test.cpp
+++ b/init/service_test.cpp
@@ -39,7 +39,7 @@
std::vector<std::string> dummy_args{"/bin/test"};
Service* service_in_old_memory =
- new (old_memory) Service("test_old_memory", nullptr, dummy_args);
+ new (old_memory) Service("test_old_memory", nullptr, /*filename=*/"", dummy_args);
EXPECT_EQ(0U, service_in_old_memory->flags());
EXPECT_EQ(0, service_in_old_memory->pid());
@@ -58,7 +58,8 @@
}
Service* service_in_old_memory2 = new (old_memory) Service(
- "test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), 0U, "", nullptr, dummy_args);
+ "test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), 0U, "",
+ nullptr, /*filename=*/"", dummy_args);
EXPECT_EQ(0U, service_in_old_memory2->flags());
EXPECT_EQ(0, service_in_old_memory2->pid());
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index bd2bec5..961e006 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -251,11 +251,8 @@
}
bool Subcontext::PathMatchesSubcontext(const std::string& path) const {
- static const std::string kApexDir = "/apex/";
- if (StartsWith(path, kApexDir)) {
- auto begin = kApexDir.size();
- auto end = path.find('/', begin);
- auto apex_name = path.substr(begin, end - begin);
+ auto apex_name = GetApexNameFromFileName(path);
+ if (!apex_name.empty()) {
return std::find(apex_list_.begin(), apex_list_.end(), apex_name) != apex_list_.end();
}
for (const auto& prefix : path_prefixes_) {
diff --git a/init/util.cpp b/init/util.cpp
index 523cce4..bfc3fb6 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -738,5 +738,15 @@
return has;
}
+std::string GetApexNameFromFileName(const std::string& path) {
+ static const std::string kApexDir = "/apex/";
+ if (StartsWith(path, kApexDir)) {
+ auto begin = kApexDir.size();
+ auto end = path.find('/', begin);
+ return path.substr(begin, end - begin);
+ }
+ return "";
+}
+
} // namespace init
} // namespace android
diff --git a/init/util.h b/init/util.h
index 099b9ee..daec470 100644
--- a/init/util.h
+++ b/init/util.h
@@ -107,5 +107,7 @@
bool IsMicrodroid();
bool Has32BitAbi();
+
+std::string GetApexNameFromFileName(const std::string& path);
} // namespace init
} // namespace android
diff --git a/libsync/libsync.map.txt b/libsync/libsync.map.txt
index aac6b57..32df91e 100644
--- a/libsync/libsync.map.txt
+++ b/libsync/libsync.map.txt
@@ -19,7 +19,7 @@
sync_merge; # introduced=26
sync_file_info; # introduced=26
sync_file_info_free; # introduced=26
- sync_wait; # llndk apex
+ sync_wait; # llndk systemapi
sync_fence_info; # llndk
sync_pt_info; # llndk
sync_fence_info_free; # llndk
diff --git a/libvndksupport/libvndksupport.map.txt b/libvndksupport/libvndksupport.map.txt
index a44ed18..1d94b9d 100644
--- a/libvndksupport/libvndksupport.map.txt
+++ b/libvndksupport/libvndksupport.map.txt
@@ -1,8 +1,8 @@
LIBVNDKSUPPORT {
global:
- android_is_in_vendor_process; # llndk apex
- android_load_sphal_library; # llndk apex
- android_unload_sphal_library; # llndk apex
+ android_is_in_vendor_process; # llndk systemapi
+ android_load_sphal_library; # llndk systemapi
+ android_unload_sphal_library; # llndk systemapi
local:
*;
};
diff --git a/trusty/storage/proxy/proxy.c b/trusty/storage/proxy/proxy.c
index 2620034..7cbc24f 100644
--- a/trusty/storage/proxy/proxy.c
+++ b/trusty/storage/proxy/proxy.c
@@ -70,49 +70,6 @@
exit(code);
}
-static int drop_privs(void) {
- struct __user_cap_header_struct capheader;
- struct __user_cap_data_struct capdata[2];
-
- if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
- return -1;
- }
-
- /*
- * ensure we're running as the system user
- */
- if (setgid(AID_SYSTEM) != 0) {
- return -1;
- }
-
- if (setuid(AID_SYSTEM) != 0) {
- return -1;
- }
-
- /*
- * drop all capabilities except SYS_RAWIO
- */
- memset(&capheader, 0, sizeof(capheader));
- memset(&capdata, 0, sizeof(capdata));
- capheader.version = _LINUX_CAPABILITY_VERSION_3;
- capheader.pid = 0;
-
- capdata[CAP_TO_INDEX(CAP_SYS_RAWIO)].permitted = CAP_TO_MASK(CAP_SYS_RAWIO);
- capdata[CAP_TO_INDEX(CAP_SYS_RAWIO)].effective = CAP_TO_MASK(CAP_SYS_RAWIO);
-
- if (capset(&capheader, &capdata[0]) < 0) {
- return -1;
- }
-
- /*
- * No access for group and other. We need execute access for user to create
- * an accessible directory.
- */
- umask(S_IRWXG | S_IRWXO);
-
- return 0;
-}
-
static int handle_req(struct storage_msg* msg, const void* req, size_t req_len) {
int rc;
@@ -260,8 +217,11 @@
int main(int argc, char* argv[]) {
int rc;
- /* drop privileges */
- if (drop_privs() < 0) return EXIT_FAILURE;
+ /*
+ * No access for group and other. We need execute access for user to create
+ * an accessible directory.
+ */
+ umask(S_IRWXG | S_IRWXO);
/* parse arguments */
parse_args(argc, argv);
diff --git a/trusty/test/binder/aidl/ByteEnum.aidl b/trusty/test/binder/aidl/ByteEnum.aidl
new file mode 100644
index 0000000..d3a13ac
--- /dev/null
+++ b/trusty/test/binder/aidl/ByteEnum.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+/*
+ * Hello, world!
+ */
+@Backing(type="byte")
+enum ByteEnum {
+ // Comment about FOO.
+ FOO = 1,
+ BAR = 2,
+ BAZ,
+}
diff --git a/trusty/test/binder/aidl/ITestService.aidl b/trusty/test/binder/aidl/ITestService.aidl
new file mode 100644
index 0000000..c6a99c8
--- /dev/null
+++ b/trusty/test/binder/aidl/ITestService.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+
+import ByteEnum;
+import IntEnum;
+import LongEnum;
+
+interface ITestService {
+ const @utf8InCpp String PORT = "com.android.trusty.binder.test.service";
+
+ const int TEST_CONSTANT = 42;
+ const int TEST_CONSTANT2 = -42;
+ const int TEST_CONSTANT3 = +42;
+ const int TEST_CONSTANT4 = +4;
+ const int TEST_CONSTANT5 = -4;
+ const int TEST_CONSTANT6 = -0;
+ const int TEST_CONSTANT7 = +0;
+ const int TEST_CONSTANT8 = 0;
+ const int TEST_CONSTANT9 = 0x56;
+ const int TEST_CONSTANT10 = 0xa5;
+ const int TEST_CONSTANT11 = 0xFA;
+ const int TEST_CONSTANT12 = 0xffffffff;
+
+ const byte BYTE_TEST_CONSTANT = 17;
+ const long LONG_TEST_CONSTANT = 1L << 40;
+
+ const String STRING_TEST_CONSTANT = "foo";
+ const String STRING_TEST_CONSTANT2 = "bar";
+
+ // Test that primitives work as parameters and return types.
+ boolean RepeatBoolean(boolean token);
+ byte RepeatByte(byte token);
+ char RepeatChar(char token);
+ int RepeatInt(int token);
+ long RepeatLong(long token);
+ float RepeatFloat(float token);
+ double RepeatDouble(double token);
+ String RepeatString(String token);
+ ByteEnum RepeatByteEnum(ByteEnum token);
+ IntEnum RepeatIntEnum(IntEnum token);
+ LongEnum RepeatLongEnum(LongEnum token);
+
+ // Test that arrays work as parameters and return types.
+ boolean[] ReverseBoolean(in boolean[] input, out boolean[] repeated);
+ byte[] ReverseByte(in byte[] input, out byte[] repeated);
+ char[] ReverseChar(in char[] input, out char[] repeated);
+ int[] ReverseInt(in int[] input, out int[] repeated);
+ long[] ReverseLong(in long[] input, out long[] repeated);
+ float[] ReverseFloat(in float[] input, out float[] repeated);
+ double[] ReverseDouble(in double[] input, out double[] repeated);
+ String[] ReverseString(in String[] input, out String[] repeated);
+ ByteEnum[] ReverseByteEnum(in ByteEnum[] input, out ByteEnum[] repeated);
+ IntEnum[] ReverseIntEnum(in IntEnum[] input, out IntEnum[] repeated);
+ LongEnum[] ReverseLongEnum(in LongEnum[] input, out LongEnum[] repeated);
+}
diff --git a/trusty/test/binder/aidl/IntEnum.aidl b/trusty/test/binder/aidl/IntEnum.aidl
new file mode 100644
index 0000000..120e44f
--- /dev/null
+++ b/trusty/test/binder/aidl/IntEnum.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum IntEnum {
+ FOO = 1000,
+ BAR = 2000,
+ BAZ,
+ /** @deprecated do not use this */
+ QUX,
+}
diff --git a/trusty/test/binder/aidl/LongEnum.aidl b/trusty/test/binder/aidl/LongEnum.aidl
new file mode 100644
index 0000000..0e9e933
--- /dev/null
+++ b/trusty/test/binder/aidl/LongEnum.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+@Backing(type="long")
+enum LongEnum {
+ FOO = 100000000000,
+ BAR = 200000000000,
+ BAZ,
+}
diff --git a/trusty/test/binder/aidl/rules.mk b/trusty/test/binder/aidl/rules.mk
new file mode 100644
index 0000000..6154abb
--- /dev/null
+++ b/trusty/test/binder/aidl/rules.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_AIDLS := \
+ $(LOCAL_DIR)/ByteEnum.aidl \
+ $(LOCAL_DIR)/IntEnum.aidl \
+ $(LOCAL_DIR)/ITestService.aidl \
+ $(LOCAL_DIR)/LongEnum.aidl \
+
+include make/aidl.mk