diff --git a/init/Android.mk b/init/Android.mk index 442a5f301..ecdf5db70 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -126,7 +126,6 @@ LOCAL_SRC_FILES := \ LOCAL_SHARED_LIBRARIES += \ libcutils \ libbase \ - libselinux \ LOCAL_STATIC_LIBRARIES := libinit LOCAL_SANITIZE := integer diff --git a/init/descriptors.cpp b/init/descriptors.cpp index 429a76e19..6e457cdc0 100644 --- a/init/descriptors.cpp +++ b/init/descriptors.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -89,14 +90,34 @@ const std::string SocketInfo::key() const { FileInfo::FileInfo(const std::string& name, const std::string& type, uid_t uid, gid_t gid, int perm, const std::string& context) + // defaults OK for uid,..., they are ignored for this class. : DescriptorInfo(name, type, uid, gid, perm, context) { } -int FileInfo::Create(const std::string& context) const { - int flags = ((type() == "r" ? O_RDONLY : - (type() == "w" ? (O_WRONLY | O_CREAT) : - (O_RDWR | O_CREAT)))); - return create_file(name().c_str(), flags, perm(), uid(), gid(), context.c_str()); +int FileInfo::Create(const std::string&) 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) { + PLOG(ERROR) << "Failed to open file '" << name().c_str() << "'"; + return -1; + } + + // 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().c_str() << "'" + << ", flags " << std::oct << flags << std::dec; + + return fd.release(); } const std::string FileInfo::key() const { diff --git a/init/readme.txt b/init/readme.txt index 7549e3c03..36bf69896 100644 --- a/init/readme.txt +++ b/init/readme.txt @@ -148,13 +148,10 @@ socket [ [ [ ] ] ] seclabel or computed based on the service executable file security context. For native executables see libcutils android_get_control_socket(). -file [ [ [ ] ] ] - Open/Create a file path and pass its fd to the launched process. must - be "r", "w" or "rw". User and group default to 0. 'seclabel' is the SELinux - security context for the file if it must be created. It defaults to the - service security context, as specified by seclabel or computed based on the - service executable file security context. For native executables see - libcutils android_get_control_file(). +file + Open a file path and pass its fd to the launched process. must be + "r", "w" or "rw". For native executables see libcutils + android_get_control_file(). user Change to 'username' before exec'ing this service. diff --git a/init/service.cpp b/init/service.cpp index 4b9724ddf..a7eaf6650 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -526,7 +526,7 @@ Service::OptionParserMap::Map& Service::OptionParserMap::map() const { {"seclabel", {1, 1, &Service::ParseSeclabel}}, {"setenv", {2, 2, &Service::ParseSetenv}}, {"socket", {3, 6, &Service::ParseSocket}}, - {"file", {2, 6, &Service::ParseFile}}, + {"file", {2, 2, &Service::ParseFile}}, {"user", {1, 1, &Service::ParseUser}}, {"writepid", {1, kMax, &Service::ParseWritepid}}, }; diff --git a/init/util.cpp b/init/util.cpp index 38e3b8d82..a79a41993 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -160,69 +160,6 @@ out_unlink: return -1; } -/* - * create_file - opens and creates a file as dictated in init.rc. - * This file is inherited by the daemon. We communicate the file - * descriptor's value via the environment variable ANDROID_FILE_ - */ -int create_file(const char *path, int flags, mode_t perm, uid_t uid, - gid_t gid, const char *filecon) -{ - char *secontext = NULL; - - if (filecon) { - if (setsockcreatecon(filecon) == -1) { - PLOG(ERROR) << "setsockcreatecon(\"" << filecon << "\") failed"; - return -1; - } - } else if (sehandle) { - if (selabel_lookup(sehandle, &secontext, path, perm) != -1) { - if (setfscreatecon(secontext) == -1) { - freecon(secontext); // does not upset errno value - PLOG(ERROR) << "setfscreatecon(\"" << secontext << "\") failed"; - return -1; - } - } - } - - android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path, flags | O_NDELAY, perm))); - int savederrno = errno; - - if (filecon) { - setsockcreatecon(NULL); - lsetfilecon(path, filecon); - } else { - setfscreatecon(NULL); - freecon(secontext); - } - - if (fd < 0) { - errno = savederrno; - PLOG(ERROR) << "Failed to open/create file '" << path << "'"; - return -1; - } - - if (!(flags & O_NDELAY)) fcntl(fd, F_SETFD, flags); - - if (lchown(path, uid, gid)) { - PLOG(ERROR) << "Failed to lchown file '" << path << "'"; - return -1; - } - if (perm != static_cast(-1)) { - if (fchmodat(AT_FDCWD, path, perm, AT_SYMLINK_NOFOLLOW)) { - PLOG(ERROR) << "Failed to fchmodat file '" << path << "'"; - return -1; - } - } - - LOG(INFO) << "Created file '" << path << "'" - << ", mode " << std::oct << perm << std::dec - << ", user " << uid - << ", group " << gid; - - return fd.release(); -} - bool read_file(const char* path, std::string* content) { content->clear(); diff --git a/init/util.h b/init/util.h index 4b5436145..e63c46996 100644 --- a/init/util.h +++ b/init/util.h @@ -31,8 +31,6 @@ using namespace std::chrono_literals; int create_socket(const char *name, int type, mode_t perm, uid_t uid, gid_t gid, const char *socketcon); -int create_file(const char *path, int mode, mode_t perm, - uid_t uid, gid_t gid, const char *filecon); bool read_file(const char* path, std::string* content); int write_file(const char* path, const char* content); diff --git a/init/util_test.cpp b/init/util_test.cpp index e9f164d82..24c75c42d 100644 --- a/init/util_test.cpp +++ b/init/util_test.cpp @@ -16,19 +16,9 @@ #include "util.h" -#include #include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include TEST(util, read_file_ENOENT) { std::string s("hello"); @@ -52,54 +42,3 @@ TEST(util, decode_uid) { EXPECT_EQ(UINT_MAX, decode_uid("toot")); EXPECT_EQ(123U, decode_uid("123")); } - -struct selabel_handle *sehandle; - -TEST(util, create_file) { - if (!sehandle) sehandle = selinux_android_file_context_handle(); - - TemporaryFile tf; - close(tf.fd); - EXPECT_GE(unlink(tf.path), 0); - - std::string key(ANDROID_FILE_ENV_PREFIX); - key += tf.path; - - std::for_each(key.begin(), key.end(), [] (char& c) { c = isalnum(c) ? c : '_'; }); - - EXPECT_EQ(unsetenv(key.c_str()), 0); - - uid_t uid = decode_uid("logd"); - gid_t gid = decode_uid("system"); - mode_t perms = S_IRWXU | S_IWGRP | S_IRGRP | S_IROTH; - static const char context[] = "u:object_r:misc_logd_file:s0"; - EXPECT_GE(tf.fd = create_file(tf.path, O_RDWR | O_CREAT, perms, uid, gid, context), 0); - if (tf.fd < 0) return; - static const char hello[] = "hello world\n"; - static const ssize_t len = strlen(hello); - EXPECT_EQ(write(tf.fd, hello, len), len); - char buffer[sizeof(hello) + 1]; - memset(buffer, 0, sizeof(buffer)); - EXPECT_GE(lseek(tf.fd, 0, SEEK_SET), 0); - EXPECT_EQ(read(tf.fd, buffer, sizeof(buffer)), len); - EXPECT_EQ(std::string(hello), buffer); - EXPECT_EQ(android_get_control_file(tf.path), -1); - EXPECT_EQ(setenv(key.c_str(), android::base::StringPrintf("%d", tf.fd).c_str(), true), 0); - EXPECT_EQ(android_get_control_file(tf.path), tf.fd); - close(tf.fd); - EXPECT_EQ(android_get_control_file(tf.path), -1); - EXPECT_EQ(unsetenv(key.c_str()), 0); - struct stat st; - EXPECT_EQ(stat(tf.path, &st), 0); - EXPECT_EQ(st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO), perms); - EXPECT_EQ(st.st_uid, uid); - EXPECT_EQ(st.st_gid, gid); - security_context_t con; - EXPECT_GE(getfilecon(tf.path, &con), 0); - EXPECT_NE(con, static_cast(NULL)); - if (con) { - EXPECT_EQ(context, std::string(con)); - } - freecon(con); - EXPECT_EQ(unlink(tf.path), 0); -}