summaryrefslogtreecommitdiff
path: root/init/service_utils.cpp
diff options
context:
space:
mode:
authorTom Cherry <tomcherry@google.com>2019-07-09 13:33:36 -0700
committerTom Cherry <tomcherry@google.com>2019-07-15 12:17:30 -0700
commit2e4c85f157bd52d4daaf0b4e67280aa72f98da07 (patch)
treebb553134c66c156072cc747c99d93812acc5bc5f /init/service_utils.cpp
parent8a779ee959996b413a8539d2a571e34803be0bf5 (diff)
init: clean up file / socket descriptor creation
clang-tidy hinted that some of this code wasn't right. Looking deeper, there is really not much related to file and socket descriptors, except that they're published in similar ways to the environment. All of the abstraction into a 'Descriptor' class takes us further away from specifying what we really mean. This removes that abstraction, adds stricter checks and better errors for parsing init scripts, reports sockets and files that are unable to be acquired before exec, and updates the README.md for the passcred option. Test: build, logd (uses files and sockets) works Change-Id: I59e611e95c85bdbefa779ef69b32b9dd4ee203e2
Diffstat (limited to 'init/service_utils.cpp')
-rw-r--r--init/service_utils.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/init/service_utils.cpp b/init/service_utils.cpp
index 34aa8370f..836145d62 100644
--- a/init/service_utils.cpp
+++ b/init/service_utils.cpp
@@ -27,9 +27,12 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
+#include <cutils/android_get_control_file.h>
+#include <cutils/sockets.h>
#include <processgroup/processgroup.h>
#include "mount_namespace.h"
+#include "util.h"
using android::base::GetProperty;
using android::base::StartsWith;
@@ -135,8 +138,52 @@ void OpenConsole(const std::string& console) {
dup2(fd, 2);
}
+void PublishDescriptor(const std::string& key, const std::string& name, int fd) {
+ std::string published_name = key + name;
+ for (auto& c : published_name) {
+ c = isalnum(c) ? c : '_';
+ }
+
+ std::string val = std::to_string(fd);
+ setenv(published_name.c_str(), val.c_str(), 1);
+}
+
} // namespace
+Result<void> SocketDescriptor::CreateAndPublish(const std::string& global_context) const {
+ const auto& socket_context = context.empty() ? global_context : context;
+ auto result = CreateSocket(name, type, passcred, perm, uid, gid, socket_context);
+ if (!result) {
+ return result.error();
+ }
+
+ PublishDescriptor(ANDROID_SOCKET_ENV_PREFIX, name, *result);
+
+ return {};
+}
+
+Result<void> FileDescriptor::CreateAndPublish() const {
+ int flags = (type == "r") ? O_RDONLY : (type == "w") ? O_WRONLY : O_RDWR;
+
+ // Make sure we do not block on open (eg: devices can chose to block on carrier detect). Our
+ // intention is never to delay launch of a service for such a condition. The service can
+ // perform its own blocking on carrier detect.
+ android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(name.c_str(), flags | O_NONBLOCK)));
+
+ if (fd < 0) {
+ return ErrnoError() << "Failed to open file '" << name << "'";
+ }
+
+ // Fixup as we set O_NONBLOCK for open, the intent for fd is to block reads.
+ fcntl(fd, F_SETFL, flags);
+
+ LOG(INFO) << "Opened file '" << name << "', flags " << flags;
+
+ PublishDescriptor(ANDROID_FILE_ENV_PREFIX, name, fd.release());
+
+ return {};
+}
+
Result<void> EnterNamespaces(const NamespaceInfo& info, const std::string& name, bool pre_apexd) {
for (const auto& [nstype, path] : info.namespaces_to_enter) {
if (auto result = EnterNamespace(nstype, path.c_str()); !result) {