Merge "init: Shutdown services and umount partitions" into main
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 3f8a415..1c52da2 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -588,12 +588,6 @@
" Delete a logical partition with the given name.\n"
" resize-logical-partition NAME SIZE\n"
" Change the size of the named logical partition.\n"
- " update-super NAME\n"
- " Merges changes to the super partition metadata.\n"
- " If a merge isn't possible (for example, the format\n"
- " on the device is an unsupported version), then this\n"
- " command fails. An optional wipe parameter overwrites\n"
- " the device's metadata, rather than performing a merge.\n"
" snapshot-update cancel On devices that support snapshot-based updates, cancel\n"
" an in-progress update. This may make the device\n"
" unbootable until it is reflashed.\n"
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h
index 991e17c..66f9a83 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_format.h
@@ -329,6 +329,16 @@
uint8_t read_ahead_state;
} __attribute__((packed));
+constexpr size_t GetCowOpSize(size_t version) {
+ if (version == 3) {
+ return sizeof(CowOperationV3);
+ } else if (version == 2 || version == 1) {
+ return sizeof(CowOperationV2);
+ } else {
+ return 0;
+ }
+}
+
// 2MB Scratch space used for read-ahead
static constexpr uint64_t BUFFER_REGION_DEFAULT_SIZE = (1ULL << 21);
diff --git a/init/README.md b/init/README.md
index 251fe98..89e20a4 100644
--- a/init/README.md
+++ b/init/README.md
@@ -454,44 +454,66 @@
Triggers
--------
-Triggers are strings which can be used to match certain kinds of
-events and used to cause an action to occur.
+Triggers of an action specifies one or more conditions when satisfied
+execute the commands in the action. A trigger encodes a single atomic
+condition, and multiple triggers can be combined using the `&&`
+operator to form a bigger AND condition.
-Triggers are subdivided into event triggers and property triggers.
-
-Event triggers are strings triggered by the 'trigger' command or by
-the QueueEventTrigger() function within the init executable. These
-take the form of a simple string such as 'boot' or 'late-init'.
-
-Property triggers are strings triggered when a named property changes
-value to a given new value or when a named property changes value to
-any new value. These take the form of 'property:<name>=<value>' and
-'property:<name>=\*' respectively. Property triggers are additionally
-evaluated and triggered accordingly during the initial boot phase of
-init.
-
-An Action can have multiple property triggers but may only have one
+There are two types of triggers: event triggers and action triggers.
+An action can have multiple property triggers but may have only one
event trigger.
-For example:
-`on boot && property:a=b` defines an action that is only executed when
-the 'boot' event trigger happens and the property a equals b at the moment. This
-will NOT be executed when the property a transitions to value b after the `boot`
-event was triggered.
+An event trigger takes the simple form of `<event>` where `<event>` is
+the name of a boot stage like `early-init` or `boot`. This trigger
+is satisfied when init reaches the stage via the `trigger` command or
+by the `QueueEventTrigger()` function in the init executable.
-`on property:a=b && property:c=d` defines an action that is executed
-at three times:
+A property trigger takes the form of `property:<name>=<value>`. This
+trigger is satisfied when the property of name `<name>` is found to
+have the value of `<value>` when the check is made. The `<value>` part
+can be `\*` to match with any value.
- 1. During initial boot if property a=b and property c=d.
- 2. Any time that property a transitions to value b, while property c already equals d.
- 3. Any time that property c transitions to value d, while property a already equals b.
+The check for property trigger is made in the following cases:
-Note that, for bootloader-provided properties (ro.boot.*), their action cannot be
-auto-triggered until `boot` stage. If they need to be triggered earlier, like at `early-boot`
-stage, they should be tied to the `event`. For example:
+* All property triggers get checked at least once when the `boot`
+ event is finished (i.e. when the last command under `on boot ...` is
+finished).
-`on early-boot && property:a=b`.
+* After the one-time check, `property:a=b` is checked when property `a`
+ is newly created, or when the property is set to a new value.
+* Property triggers are also checked when other triggers in the same
+ action are checked. For example, `property:a=b && property:c=d` is
+checked not only when property `a` gets a new value, but also when
+property `c` gets a new value (and of course when the one-time check
+is made).
+
+* Before the one-time check, `property:a=b` without an event trigger
+ is NOT checked, even if property `a` gets a new value. Care must be
+taken since this is a non-intuitive behavior, which unfortunately
+can't be changed due to compatibility concerns.
+
+Some examples:
+
+`on property:a=b` is executed in two cases:
+
+1. during the one-time check if property `a` is `b` at the moment.
+2. if property `a` is set to or changed to `b` after the one-time
+ check, but not before then.
+
+`on property:a=b && property:c=d` is executed in three cases:
+
+1. during the one-time check if property `a` is `b` and property `c`
+ is `d` at the moment.
+2. (after the one-time check) property `a` becomes `b` while property
+ `c` already equals to `d`.
+3. (after the one-time check) property `c` becomes `d` while property
+ `a` already equals to `b`.
+
+`on property:a=b && post-fs` is executed in one case only:
+
+1. `post-fs` is triggered while property `a` already equals to `b`.
+ This is NOT executed when property `a` becomes `b` AFTER `post-fs`.
Trigger Sequence
----------------
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 8bdf5b6..2a27c1d 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -749,7 +749,7 @@
PLOG(FATAL) << "Failed to unlink " << or_dest;
}
const char* args[] = {or_dest.c_str(), nullptr};
- fexecve(dest.get(), const_cast<char**>(args), nullptr);
+ fexecve(dest.get(), const_cast<char**>(args), environ);
// execv() only returns if an error happened, in which case we
// panic and never return from this function.
diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc
index 1915f22..269f300 100644
--- a/libappfuse/FuseBuffer.cc
+++ b/libappfuse/FuseBuffer.cc
@@ -35,6 +35,8 @@
namespace {
constexpr useconds_t kRetrySleepForWriting = 1000; // 1 ms
+// This makes the total wait time to allocate a buffer 5 seconds
+const int kNumberOfRetriesForWriting = 5000;
template <typename T>
bool CheckHeaderLength(const FuseMessage<T>* self, const char* name, size_t max_size) {
@@ -92,6 +94,7 @@
const char* const buf = reinterpret_cast<const char*>(self);
const auto& header = static_cast<const T*>(self)->header;
+ int retry = kNumberOfRetriesForWriting;
while (true) {
int result;
@@ -110,8 +113,14 @@
case ENOBUFS:
// When returning ENOBUFS, epoll still reports the FD is writable. Just usleep
// and retry again.
- usleep(kRetrySleepForWriting);
- continue;
+ if (retry > 0) {
+ usleep(kRetrySleepForWriting);
+ retry--;
+ continue;
+ } else {
+ LOG(ERROR) << "Failed to write a FUSE message: ENOBUFS retries are failed";
+ return ResultOrAgain::kFailure;
+ }
case EAGAIN:
return ResultOrAgain::kAgain;
default:
diff --git a/libsysutils/src/OWNERS b/libsysutils/src/OWNERS
index 3244fe8..a3e4c70 100644
--- a/libsysutils/src/OWNERS
+++ b/libsysutils/src/OWNERS
@@ -1,2 +1 @@
-per-file OWNERS,Netlink* = jchalard@google.com, lorenzo@google.com, maze@google.com, satk@google.com
-
+per-file OWNERS,Netlink* = file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
diff --git a/llkd/OWNERS b/llkd/OWNERS
index b6af537..b15bb48 100644
--- a/llkd/OWNERS
+++ b/llkd/OWNERS
@@ -1,2 +1 @@
-salyzyn@google.com
surenb@google.com
diff --git a/storaged/OWNERS b/storaged/OWNERS
index d033f00..9e70e7d 100644
--- a/storaged/OWNERS
+++ b/storaged/OWNERS
@@ -1,2 +1 @@
-salyzyn@google.com
dvander@google.com
diff --git a/trusty/fuzz/tipc_fuzzer.cpp b/trusty/fuzz/tipc_fuzzer.cpp
index d5e23e0..f9f6c8c 100644
--- a/trusty/fuzz/tipc_fuzzer.cpp
+++ b/trusty/fuzz/tipc_fuzzer.cpp
@@ -97,48 +97,47 @@
static_assert(MAX_CONNECTIONS >= 1);
// Either
- // 1. Add a new TA and connect.
- // 2. Remove a TA.
- // 3. Send a random message to a random TA.
+ // 1. (20%) Add a new TA and connect.
+ // 2. (20%) Remove a TA.
+ // 3. (60%) Send a random message to a random TA.
+ auto add_ta = [&]() {
+ if (trustyApps.size() >= MAX_CONNECTIONS) {
+ return;
+ }
+ auto& ta = trustyApps.emplace_back(TIPC_DEV, TRUSTY_APP_PORT);
+ abortResult(ta.Connect());
+ };
+ auto remove_ta = [&]() {
+ if (trustyApps.empty()) {
+ return;
+ }
+ trustyApps.pop_back();
+ };
+ auto send_message = [&]() {
+ if (trustyApps.empty()) {
+ return;
+ }
+
+ // Choose a random TA.
+ const auto i = provider.ConsumeIntegralInRange<size_t>(0, trustyApps.size() - 1);
+ std::swap(trustyApps[i], trustyApps.back());
+ auto& ta = trustyApps.back();
+
+ // Send a random message.
+ const auto data = provider.ConsumeRandomLengthString();
+ abortResult(ta.Write(data.data(), data.size()));
+
+ std::array<uint8_t, TIPC_MAX_MSG_SIZE> buf;
+ abortResult(ta.Read(buf.data(), buf.size()));
+
+ // Reconnect to ensure that the service is still up.
+ ta.Disconnect();
+ abortResult(ta.Connect());
+ };
const std::function<void()> options[] = {
- // Add a new TA and connect.
- [&]() {
- if (trustyApps.size() >= MAX_CONNECTIONS) {
- return;
- }
- auto& ta = trustyApps.emplace_back(TIPC_DEV, TRUSTY_APP_PORT);
- abortResult(ta.Connect());
- },
- // Remove a TA.
- [&]() {
- if (trustyApps.empty()) {
- return;
- }
- trustyApps.pop_back();
- },
- // Send a random message to a random TA.
- [&]() {
- if (trustyApps.empty()) {
- return;
- }
-
- // Choose a random TA.
- const auto i =
- provider.ConsumeIntegralInRange<size_t>(0, trustyApps.size() - 1);
- std::swap(trustyApps[i], trustyApps.back());
- auto& ta = trustyApps.back();
-
- // Send a random message.
- const auto data = provider.ConsumeRandomLengthString();
- abortResult(ta.Write(data.data(), data.size()));
-
- std::array<uint8_t, TIPC_MAX_MSG_SIZE> buf;
- abortResult(ta.Read(buf.data(), buf.size()));
-
- // Reconnect to ensure that the service is still up.
- ta.Disconnect();
- abortResult(ta.Connect());
- },
+ add_ta, // 1x: 20%
+ remove_ta, // 1x: 20%
+ send_message, send_message, send_message, // 3x: 60%
};
provider.PickValueInArray(options)();
diff --git a/trusty/libtrusty/include/trusty/ipc.h b/trusty/libtrusty/include/trusty/ipc.h
index 04e84c6..4a19692 100644
--- a/trusty/libtrusty/include/trusty/ipc.h
+++ b/trusty/libtrusty/include/trusty/ipc.h
@@ -23,19 +23,21 @@
/**
* enum transfer_kind - How to send an fd to Trusty
- * @TRUSTY_SHARE: Memory will be accessible by Linux and Trusty. On ARM it
- * will be mapped as nonsecure. Suitable for shared memory.
- * The paired fd must be a "dma_buf".
- * @TRUSTY_LEND: Memory will be accessible only to Trusty. On ARM it will
- * be transitioned to "Secure" memory if Trusty is in
- * TrustZone. This transfer kind is suitable for donating
- * video buffers or other similar resources. The paired fd
- * may need to come from a platform-specific allocator for
- * memory that may be transitioned to "Secure".
- * @TRUSTY_SEND_SECURE: Send memory that is already "Secure". Memory will be
- * accessible only to Trusty. The paired fd may need to
- * come from a platform-specific allocator that returns
- * "Secure" buffers.
+ * @TRUSTY_SHARE: Memory will be accessible by Linux and Trusty. On ARM it
+ * will be mapped as nonsecure. Suitable for shared memory.
+ * The paired fd must be a "dma_buf".
+ * @TRUSTY_LEND: Memory will be accessible only to Trusty. On ARM it will
+ * be transitioned to "Secure" memory if Trusty is in
+ * TrustZone. This transfer kind is suitable for donating
+ * video buffers or other similar resources. The paired fd
+ * may need to come from a platform-specific allocator for
+ * memory that may be transitioned to "Secure".
+ * @TRUSTY_SEND_SECURE: Send memory that is already "Secure". Memory will be
+ * accessible only to Trusty. The paired fd may need to
+ * come from a platform-specific allocator that returns
+ * "Secure" buffers.
+ * @TRUSTY_SEND_SECURE_OR_SHARE: Acts as TRUSTY_SEND_SECURE if the memory is already
+ * "Secure" and as TRUSTY_SHARE otherwise.
*
* Describes how the user would like the resource in question to be sent to
* Trusty. Options may be valid only for certain kinds of fds.
@@ -44,6 +46,7 @@
TRUSTY_SHARE = 0,
TRUSTY_LEND = 1,
TRUSTY_SEND_SECURE = 2,
+ TRUSTY_SEND_SECURE_OR_SHARE = 3,
};
/**
diff --git a/trusty/libtrusty/tipc-test/tipc_test.c b/trusty/libtrusty/tipc-test/tipc_test.c
index 121837d..9910aee 100644
--- a/trusty/libtrusty/tipc-test/tipc_test.c
+++ b/trusty/libtrusty/tipc-test/tipc_test.c
@@ -55,6 +55,8 @@
"}"
/* clang-format on */
+#define countof(arr) (sizeof(arr) / sizeof(arr[0]))
+
static const char *uuid_name = "com.android.ipc-unittest.srv.uuid";
static const char *echo_name = "com.android.ipc-unittest.srv.echo";
static const char *ta_only_name = "com.android.ipc-unittest.srv.ta_only";
@@ -904,12 +906,14 @@
static int send_fd_test(const struct tipc_test_params* params) {
int ret;
- int dma_buf = -1;
+ int dma_buf[] = {-1, -1, -1};
int fd = -1;
- volatile char* buf = MAP_FAILED;
+ volatile char* buf[countof(dma_buf)] = {MAP_FAILED, MAP_FAILED, MAP_FAILED};
BufferAllocator* allocator = NULL;
+ uint i;
const size_t num_chunks = 10;
+ const size_t buf_size = memref_chunk_size * num_chunks;
fd = tipc_connect(params->dev_name, receiver_name);
if (fd < 0) {
@@ -925,56 +929,86 @@
goto cleanup;
}
- size_t buf_size = memref_chunk_size * num_chunks;
- dma_buf = DmabufHeapAlloc(allocator, "system", buf_size, 0, 0 /* legacy align */);
- if (dma_buf < 0) {
- ret = dma_buf;
- fprintf(stderr, "Failed to create dma-buf fd of size %zu err (%d)\n", buf_size, ret);
- goto cleanup;
+ for (i = 0; i < countof(dma_buf); i++) {
+ ret = DmabufHeapAlloc(allocator, "system", buf_size, 0, 0 /* legacy align */);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to create dma-buf fd of size %zu err (%d)\n", buf_size, ret);
+ goto cleanup;
+ }
+ dma_buf[i] = ret;
}
- buf = mmap(0, buf_size, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
- if (buf == MAP_FAILED) {
- fprintf(stderr, "Failed to map dma-buf: %s\n", strerror(errno));
- ret = -1;
- goto cleanup;
+ for (i = 0; i < countof(dma_buf); i++) {
+ buf[i] = mmap(0, buf_size, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf[i], 0);
+ if (buf[i] == MAP_FAILED) {
+ fprintf(stderr, "Failed to map dma-buf: %s\n", strerror(errno));
+ ret = -1;
+ goto cleanup;
+ }
+
+ strcpy((char*)buf[i], "From NS");
}
- strcpy((char*)buf, "From NS");
-
- struct trusty_shm shm = {
- .fd = dma_buf,
- .transfer = TRUSTY_SHARE,
+ struct trusty_shm shm[] = {
+ {
+ .fd = dma_buf[0],
+ .transfer = TRUSTY_SHARE,
+ },
+ {
+ .fd = dma_buf[0],
+ .transfer = TRUSTY_SEND_SECURE_OR_SHARE,
+ },
+ {
+ .fd = dma_buf[1],
+ .transfer = TRUSTY_LEND,
+ },
+ {
+ .fd = dma_buf[1],
+ .transfer = TRUSTY_SEND_SECURE_OR_SHARE,
+ },
+ {
+ .fd = dma_buf[2],
+ .transfer = TRUSTY_SEND_SECURE_OR_SHARE,
+ },
};
- ssize_t rc = tipc_send(fd, NULL, 0, &shm, 1);
- if (rc < 0) {
- fprintf(stderr, "tipc_send failed: %zd\n", rc);
- ret = rc;
- goto cleanup;
+ for (i = 0; i < countof(shm); i++) {
+ ssize_t rc = tipc_send(fd, NULL, 0, &shm[i], 1);
+ if (rc < 0) {
+ fprintf(stderr, "tipc_send failed: %zd\n", rc);
+ ret = rc;
+ goto cleanup;
+ }
+ char c;
+ read(fd, &c, 1);
}
- char c;
- read(fd, &c, 1);
- tipc_close(fd);
ret = 0;
- for (size_t skip = 0; skip < num_chunks; skip++) {
- int cmp = strcmp("Hello from Trusty!",
- (const char*)&buf[skip * memref_chunk_size]) ? (-1) : 0;
- if (cmp)
- fprintf(stderr, "Failed: Unexpected content at page %zu in dmabuf\n", skip);
- ret |= cmp;
+ for (i = 0; i < countof(buf); i++) {
+ for (size_t skip = 0; skip < num_chunks; skip++) {
+ int cmp = strcmp("Hello from Trusty!", (const char*)&buf[i][skip * memref_chunk_size])
+ ? (-1)
+ : 0;
+ if (cmp) fprintf(stderr, "Failed: Unexpected content at page %zu in dmabuf\n", skip);
+ ret |= cmp;
+ }
}
cleanup:
- if (buf != MAP_FAILED) {
- munmap((char*)buf, buf_size);
+ for (i = 0; i < countof(dma_buf); i++) {
+ if (buf[i] != MAP_FAILED) {
+ munmap((char*)buf[i], buf_size);
+ }
+ if (dma_buf[i] >= 0) {
+ close(dma_buf[i]);
+ }
}
- close(dma_buf);
if (allocator) {
FreeDmabufHeapBufferAllocator(allocator);
}
- tipc_close(fd);
+ if (fd >= 0) {
+ tipc_close(fd);
+ }
return ret;
}
diff --git a/trusty/trusty-storage.mk b/trusty/trusty-storage.mk
index 5bfbf1e..d2bc0b1 100644
--- a/trusty/trusty-storage.mk
+++ b/trusty/trusty-storage.mk
@@ -38,6 +38,6 @@
storageproxyd.system \
rpmb_dev.test.system \
rpmb_dev.system \
- # rpmb_dev.wv.system \
+ rpmb_dev.wv.system \
endif
diff --git a/trusty/utils/rpmb_dev/rpmb_dev.wv.system.rc b/trusty/utils/rpmb_dev/rpmb_dev.wv.system.rc
index 4e42d46..ac18f81 100644
--- a/trusty/utils/rpmb_dev/rpmb_dev.wv.system.rc
+++ b/trusty/utils/rpmb_dev/rpmb_dev.wv.system.rc
@@ -4,7 +4,6 @@
-p /data/secure_storage_wv_system \
-t sock
disabled
- class hal
user system
group system
@@ -47,3 +46,9 @@
chown root system /data/secure_storage_wv_system/persist
exec_start rpmb_mock_init_wv_system
start rpmb_mock_wv_system
+
+on post-fs-data && \
+ property:trusty.widevine_vm.nonsecure_vm_ready=1 && \
+ property:trusty.widevine_vm.vm_cid=*
+ start storageproxyd_wv_system
+