Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f22788f authored by Mark Salyzyn's avatar Mark Salyzyn Committed by android-build-merger
Browse files

Merge "init: service file command only opens existing files"

am: bd3f4201

Change-Id: Id4c0e6b26e8b3295ebfd5387bfad2e8795531175
parents 6e2bd60c bd3f4201
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -126,7 +126,6 @@ LOCAL_SRC_FILES := \
LOCAL_SHARED_LIBRARIES += \
    libcutils \
    libbase \
    libselinux \

LOCAL_STATIC_LIBRARIES := libinit
LOCAL_SANITIZE := integer
+26 −5
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <unistd.h>

#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <cutils/android_get_control_file.h>
#include <cutils/sockets.h>

@@ -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 {
+4 −7
Original line number Diff line number Diff line
@@ -148,13 +148,10 @@ socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]
  seclabel or computed based on the service executable file security context.
  For native executables see libcutils android_get_control_socket().

file <path> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]
  Open/Create a file path and pass its fd to the launched process.  <type> 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 <path> <type>
  Open a file path and pass its fd to the launched process.  <type> must be
  "r", "w" or "rw".  For native executables see libcutils
  android_get_control_file().

user <username>
  Change to 'username' before exec'ing this service.
+1 −1
Original line number Diff line number Diff line
@@ -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}},
    };
+0 −63
Original line number Diff line number Diff line
@@ -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_<basename>
 */
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<mode_t>(-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();

Loading