init: always expand args in subcontext

Currently init expands properties in arguments only when those
commands are run in a subcontext.  This creates a hole where
properties that should not be accessible from a given subcontext of
init can be accessed when running a command in the main init
executable (for example `start`).

This change creates a callback in subcontext init that simply expands
and returns arguments back to the main init process, to ensure that
only those properties that a subcontext can access get expanded.

Bug: 62875318
Test: boot bullhead, new unit tests
Change-Id: I2850009e70da877c08e4cc83350c727b0ea98796
diff --git a/init/action.cpp b/init/action.cpp
index ab51eea..16ecdcd 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -50,12 +50,19 @@
     : func_(std::move(f)), execute_in_subcontext_(execute_in_subcontext), args_(args), line_(line) {}
 
 Result<Success> Command::InvokeFunc(Subcontext* subcontext) const {
-    if (execute_in_subcontext_ && subcontext) {
-        return subcontext->Execute(args_);
-    } else {
-        const std::string& context = subcontext ? subcontext->context() : kInitContext;
-        return RunBuiltinFunction(func_, args_, context);
+    if (subcontext) {
+        if (execute_in_subcontext_) {
+            return subcontext->Execute(args_);
+        }
+
+        auto expanded_args = subcontext->ExpandArgs(args_);
+        if (!expanded_args) {
+            return expanded_args.error();
+        }
+        return RunBuiltinFunction(func_, *expanded_args, subcontext->context());
     }
+
+    return RunBuiltinFunction(func_, args_, kInitContext);
 }
 
 std::string Command::BuildCommandString() const {