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

Commit 4adbd290 authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge "Revert "Reland: "init: run property service in a thread"""

parents 88bba959 3da2ba6d
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -130,7 +130,6 @@ cc_library_static {
        "persistent_properties.cpp",
        "persistent_properties.cpp",
        "persistent_properties.proto",
        "persistent_properties.proto",
        "property_service.cpp",
        "property_service.cpp",
        "property_service.proto",
        "property_type.cpp",
        "property_type.cpp",
        "reboot.cpp",
        "reboot.cpp",
        "reboot_utils.cpp",
        "reboot_utils.cpp",
+0 −10
Original line number Original line Diff line number Diff line
@@ -80,7 +80,6 @@
using namespace std::literals::string_literals;
using namespace std::literals::string_literals;


using android::base::Basename;
using android::base::Basename;
using android::base::StartsWith;
using android::base::unique_fd;
using android::base::unique_fd;
using android::fs_mgr::Fstab;
using android::fs_mgr::Fstab;
using android::fs_mgr::ReadFstabFromFile;
using android::fs_mgr::ReadFstabFromFile;
@@ -701,15 +700,6 @@ static Result<void> do_swapon_all(const BuiltinArguments& args) {
}
}


static Result<void> do_setprop(const BuiltinArguments& args) {
static Result<void> do_setprop(const BuiltinArguments& args) {
    if (StartsWith(args[1], "ctl.")) {
        return Error() << "InitPropertySet: Do not set ctl. properties from init; call the Service "
                          "functions directly";
    }
    if (args[1] == kRestoreconProperty) {
        return Error() << "InitPropertySet: Do not set '" << kRestoreconProperty
                       << "' from init; use the restorecon builtin directly";
    }

    property_set(args[1], args[2]);
    property_set(args[1], args[2]);
    return {};
    return {};
}
}
+1 −50
Original line number Original line Diff line number Diff line
@@ -28,9 +28,6 @@
#include <sys/types.h>
#include <sys/types.h>
#include <unistd.h>
#include <unistd.h>


#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>

#include <functional>
#include <functional>
#include <map>
#include <map>
#include <memory>
#include <memory>
@@ -64,7 +61,6 @@
#include "mount_handler.h"
#include "mount_handler.h"
#include "mount_namespace.h"
#include "mount_namespace.h"
#include "property_service.h"
#include "property_service.h"
#include "proto_utils.h"
#include "reboot.h"
#include "reboot.h"
#include "reboot_utils.h"
#include "reboot_utils.h"
#include "security.h"
#include "security.h"
@@ -73,7 +69,6 @@
#include "service.h"
#include "service.h"
#include "service_parser.h"
#include "service_parser.h"
#include "sigchld_handler.h"
#include "sigchld_handler.h"
#include "system/core/init/property_service.pb.h"
#include "util.h"
#include "util.h"


using namespace std::chrono_literals;
using namespace std::chrono_literals;
@@ -95,7 +90,6 @@ static int property_triggers_enabled = 0;
static char qemu[32];
static char qemu[32];


static int signal_fd = -1;
static int signal_fd = -1;
static int property_fd = -1;


static std::unique_ptr<Timer> waiting_for_prop(nullptr);
static std::unique_ptr<Timer> waiting_for_prop(nullptr);
static std::string wait_prop_name;
static std::string wait_prop_name;
@@ -619,44 +613,6 @@ static void RecordStageBoottimes(const boot_clock::time_point& second_stage_star
                                selinux_start_time_ns));
                                selinux_start_time_ns));
}
}


static void HandlePropertyFd() {
    auto message = ReadMessage(property_fd);
    if (!message) {
        LOG(ERROR) << "Could not read message from property service: " << message.error();
        return;
    }

    auto property_message = PropertyMessage{};
    if (!property_message.ParseFromString(*message)) {
        LOG(ERROR) << "Could not parse message from property service";
        return;
    }

    switch (property_message.msg_case()) {
        case PropertyMessage::kControlMessage: {
            auto& control_message = property_message.control_message();
            bool success = HandleControlMessage(control_message.msg(), control_message.name(),
                                                control_message.pid());

            uint32_t response = success ? PROP_SUCCESS : PROP_ERROR_HANDLE_CONTROL_MESSAGE;
            if (control_message.has_fd()) {
                int fd = control_message.fd();
                TEMP_FAILURE_RETRY(send(fd, &response, sizeof(response), 0));
                close(fd);
            }
            break;
        }
        case PropertyMessage::kChangedMessage: {
            auto& changed_message = property_message.changed_message();
            property_changed(changed_message.name(), changed_message.value());
            break;
        }
        default:
            LOG(ERROR) << "Unknown message type from property service: "
                       << property_message.msg_case();
    }
}

int SecondStageMain(int argc, char** argv) {
int SecondStageMain(int argc, char** argv) {
    if (REBOOT_BOOTLOADER_ON_PANIC) {
    if (REBOOT_BOOTLOADER_ON_PANIC) {
        InstallRebootSignalHandlers();
        InstallRebootSignalHandlers();
@@ -728,12 +684,7 @@ int SecondStageMain(int argc, char** argv) {
    UmountDebugRamdisk();
    UmountDebugRamdisk();
    fs_mgr_vendor_overlay_mount_all();
    fs_mgr_vendor_overlay_mount_all();
    export_oem_lock_status();
    export_oem_lock_status();

    StartPropertyService(&epoll);
    StartPropertyService(&property_fd);
    if (auto result = epoll.RegisterHandler(property_fd, HandlePropertyFd); !result) {
        LOG(FATAL) << "Could not register epoll handler for property fd: " << result.error();
    }

    MountHandler mount_handler(&epoll);
    MountHandler mount_handler(&epoll);
    set_usb_controller();
    set_usb_controller();


+4 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,10 @@ namespace init {
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
Parser CreateServiceOnlyParser(ServiceList& service_list);
Parser CreateServiceOnlyParser(ServiceList& service_list);


bool HandleControlMessage(const std::string& msg, const std::string& arg, pid_t pid);

void property_changed(const std::string& name, const std::string& value);

bool start_waiting_for_property(const char *name, const char *value);
bool start_waiting_for_property(const char *name, const char *value);


void DumpState();
void DumpState();
+50 −101
Original line number Original line Diff line number Diff line
@@ -42,7 +42,6 @@
#include <map>
#include <map>
#include <memory>
#include <memory>
#include <mutex>
#include <mutex>
#include <optional>
#include <queue>
#include <queue>
#include <thread>
#include <thread>
#include <vector>
#include <vector>
@@ -64,10 +63,8 @@
#include "init.h"
#include "init.h"
#include "persistent_properties.h"
#include "persistent_properties.h"
#include "property_type.h"
#include "property_type.h"
#include "proto_utils.h"
#include "selinux.h"
#include "selinux.h"
#include "subcontext.h"
#include "subcontext.h"
#include "system/core/init/property_service.pb.h"
#include "util.h"
#include "util.h"


using namespace std::literals;
using namespace std::literals;
@@ -79,7 +76,6 @@ using android::base::StartsWith;
using android::base::StringPrintf;
using android::base::StringPrintf;
using android::base::Timer;
using android::base::Timer;
using android::base::Trim;
using android::base::Trim;
using android::base::unique_fd;
using android::base::WriteStringToFile;
using android::base::WriteStringToFile;
using android::properties::BuildTrie;
using android::properties::BuildTrie;
using android::properties::ParsePropertyInfoFile;
using android::properties::ParsePropertyInfoFile;
@@ -89,13 +85,18 @@ using android::properties::PropertyInfoEntry;
namespace android {
namespace android {
namespace init {
namespace init {


static constexpr const char kRestoreconProperty[] = "selinux.restorecon_recursive";

static bool persistent_properties_loaded = false;
static bool persistent_properties_loaded = false;


static int property_set_fd = -1;
static int property_set_fd = -1;
static int init_socket = -1;


static PropertyInfoAreaFile property_info_area;
static PropertyInfoAreaFile property_info_area;


uint32_t InitPropertySet(const std::string& name, const std::string& value);

uint32_t (*property_set)(const std::string& name, const std::string& value) = InitPropertySet;

void CreateSerializedPropertyInfo();
void CreateSerializedPropertyInfo();


struct PropertyAuditData {
struct PropertyAuditData {
@@ -163,17 +164,6 @@ static bool CheckMacPerms(const std::string& name, const char* target_context,
    return has_access;
    return has_access;
}
}


static void SendPropertyChanged(const std::string& name, const std::string& value) {
    auto property_msg = PropertyMessage{};
    auto* changed_message = property_msg.mutable_changed_message();
    changed_message->set_name(name);
    changed_message->set_value(value);

    if (auto result = SendMessage(init_socket, property_msg); !result) {
        LOG(ERROR) << "Failed to send property changed message: " << result.error();
    }
}

static uint32_t PropertySet(const std::string& name, const std::string& value, std::string* error) {
static uint32_t PropertySet(const std::string& name, const std::string& value, std::string* error) {
    size_t valuelen = value.size();
    size_t valuelen = value.size();


@@ -209,16 +199,7 @@ static uint32_t PropertySet(const std::string& name, const std::string& value, s
    if (persistent_properties_loaded && StartsWith(name, "persist.")) {
    if (persistent_properties_loaded && StartsWith(name, "persist.")) {
        WritePersistentProperty(name, value);
        WritePersistentProperty(name, value);
    }
    }
    // If init sets ro.persistent_properties.ready to true, then it has finished writing persistent
    property_changed(name, value);
    // properties, and we should write future persistent properties to disk.
    if (name == "ro.persistent_properties.ready" && value == "true") {
        persistent_properties_loaded = true;
    }
    // If init hasn't started its main loop, then it won't be handling property changed messages
    // anyway, so there's no need to try to send them.
    if (init_socket != -1) {
        SendPropertyChanged(name, value);
    }
    return PROP_SUCCESS;
    return PROP_SUCCESS;
}
}


@@ -258,10 +239,35 @@ class AsyncRestorecon {
    bool thread_started_ = false;
    bool thread_started_ = false;
};
};


uint32_t InitPropertySet(const std::string& name, const std::string& value) {
    if (StartsWith(name, "ctl.")) {
        LOG(ERROR) << "InitPropertySet: Do not set ctl. properties from init; call the Service "
                      "functions directly";
        return PROP_ERROR_INVALID_NAME;
    }
    if (name == kRestoreconProperty) {
        LOG(ERROR) << "InitPropertySet: Do not set '" << kRestoreconProperty
                   << "' from init; use the restorecon builtin directly";
        return PROP_ERROR_INVALID_NAME;
    }

    uint32_t result = 0;
    ucred cr = {.pid = 1, .uid = 0, .gid = 0};
    std::string error;
    result = HandlePropertySet(name, value, kInitContext.c_str(), cr, &error);
    if (result != PROP_SUCCESS) {
        LOG(ERROR) << "Init cannot set '" << name << "' to '" << value << "': " << error;
    }

    return result;
}

class SocketConnection {
class SocketConnection {
  public:
  public:
    SocketConnection(int socket, const ucred& cred) : socket_(socket), cred_(cred) {}
    SocketConnection(int socket, const ucred& cred) : socket_(socket), cred_(cred) {}


    ~SocketConnection() { close(socket_); }

    bool RecvUint32(uint32_t* value, uint32_t* timeout_ms) {
    bool RecvUint32(uint32_t* value, uint32_t* timeout_ms) {
        return RecvFully(value, sizeof(*value), timeout_ms);
        return RecvFully(value, sizeof(*value), timeout_ms);
    }
    }
@@ -298,9 +304,6 @@ class SocketConnection {
    }
    }


    bool SendUint32(uint32_t value) {
    bool SendUint32(uint32_t value) {
        if (!socket_.ok()) {
            return false;
        }
        int result = TEMP_FAILURE_RETRY(send(socket_, &value, sizeof(value), 0));
        int result = TEMP_FAILURE_RETRY(send(socket_, &value, sizeof(value), 0));
        return result == sizeof(value);
        return result == sizeof(value);
    }
    }
@@ -315,9 +318,7 @@ class SocketConnection {
        return true;
        return true;
    }
    }


    int Release() { return socket_.release(); }
    int socket() { return socket_; }

    int socket() { return socket_.get(); }


    const ucred& cred() { return cred_; }
    const ucred& cred() { return cred_; }


@@ -388,33 +389,11 @@ class SocketConnection {
        return bytes_left == 0;
        return bytes_left == 0;
    }
    }


    unique_fd socket_;
    int socket_;
    ucred cred_;
    ucred cred_;
};

static uint32_t SendControlMessage(const std::string& msg, const std::string& name, pid_t pid,
                                   SocketConnection* socket, std::string* error) {
    auto property_msg = PropertyMessage{};
    auto* control_message = property_msg.mutable_control_message();
    control_message->set_msg(msg);
    control_message->set_name(name);
    control_message->set_pid(pid);
    if (socket != nullptr) {
        control_message->set_fd(socket->socket());
    }


    if (auto result = SendMessage(init_socket, property_msg); !result) {
    DISALLOW_IMPLICIT_CONSTRUCTORS(SocketConnection);
        *error = "Failed to send control message: " + result.error().message();
};
        return PROP_ERROR_HANDLE_CONTROL_MESSAGE;
    }

    if (socket != nullptr) {
        // We've successfully sent the fd to init, so release it here.
        socket->Release();
    }

    return PROP_SUCCESS;
}


bool CheckControlPropertyPerms(const std::string& name, const std::string& value,
bool CheckControlPropertyPerms(const std::string& name, const std::string& value,
                               const std::string& source_context, const ucred& cr) {
                               const std::string& source_context, const ucred& cr) {
@@ -483,14 +462,15 @@ uint32_t CheckPermissions(const std::string& name, const std::string& value,


// This returns one of the enum of PROP_SUCCESS or PROP_ERROR*.
// This returns one of the enum of PROP_SUCCESS or PROP_ERROR*.
uint32_t HandlePropertySet(const std::string& name, const std::string& value,
uint32_t HandlePropertySet(const std::string& name, const std::string& value,
                           const std::string& source_context, const ucred& cr,
                           const std::string& source_context, const ucred& cr, std::string* error) {
                           SocketConnection* socket, std::string* error) {
    if (auto ret = CheckPermissions(name, value, source_context, cr, error); ret != PROP_SUCCESS) {
    if (auto ret = CheckPermissions(name, value, source_context, cr, error); ret != PROP_SUCCESS) {
        return ret;
        return ret;
    }
    }


    if (StartsWith(name, "ctl.")) {
    if (StartsWith(name, "ctl.")) {
        return SendControlMessage(name.c_str() + 4, value, cr.pid, socket, error);
        return HandleControlMessage(name.c_str() + 4, value, cr.pid)
                       ? PROP_SUCCESS
                       : PROP_ERROR_HANDLE_CONTROL_MESSAGE;
    }
    }


    // sys.powerctl is a special property that is used to make the device reboot.  We want to log
    // sys.powerctl is a special property that is used to make the device reboot.  We want to log
@@ -521,20 +501,6 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value,
    return PropertySet(name, value, error);
    return PropertySet(name, value, error);
}
}


uint32_t InitPropertySet(const std::string& name, const std::string& value) {
    uint32_t result = 0;
    ucred cr = {.pid = 1, .uid = 0, .gid = 0};
    std::string error;
    result = HandlePropertySet(name, value, kInitContext.c_str(), cr, nullptr, &error);
    if (result != PROP_SUCCESS) {
        LOG(ERROR) << "Init cannot set '" << name << "' to '" << value << "': " << error;
    }

    return result;
}

uint32_t (*property_set)(const std::string& name, const std::string& value) = InitPropertySet;

static void handle_property_set_fd() {
static void handle_property_set_fd() {
    static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */
    static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */


@@ -583,8 +549,7 @@ static void handle_property_set_fd() {


        const auto& cr = socket.cred();
        const auto& cr = socket.cred();
        std::string error;
        std::string error;
        uint32_t result =
        uint32_t result = HandlePropertySet(prop_name, prop_value, source_context, cr, &error);
                HandlePropertySet(prop_name, prop_value, source_context, cr, nullptr, &error);
        if (result != PROP_SUCCESS) {
        if (result != PROP_SUCCESS) {
            LOG(ERROR) << "Unable to set property '" << prop_name << "' from uid:" << cr.uid
            LOG(ERROR) << "Unable to set property '" << prop_name << "' from uid:" << cr.uid
                       << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error;
                       << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error;
@@ -612,12 +577,11 @@ static void handle_property_set_fd() {


        const auto& cr = socket.cred();
        const auto& cr = socket.cred();
        std::string error;
        std::string error;
        uint32_t result = HandlePropertySet(name, value, source_context, cr, &socket, &error);
        uint32_t result = HandlePropertySet(name, value, source_context, cr, &error);
        if (result != PROP_SUCCESS) {
        if (result != PROP_SUCCESS) {
            LOG(ERROR) << "Unable to set property '" << name << "' from uid:" << cr.uid
            LOG(ERROR) << "Unable to set property '" << name << "' from uid:" << cr.uid
                       << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error;
                       << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error;
        }
        }

        socket.SendUint32(result);
        socket.SendUint32(result);
        break;
        break;
      }
      }
@@ -800,6 +764,7 @@ void load_persist_props(void) {
    for (const auto& persistent_property_record : persistent_properties.properties()) {
    for (const auto& persistent_property_record : persistent_properties.properties()) {
        property_set(persistent_property_record.name(), persistent_property_record.value());
        property_set(persistent_property_record.name(), persistent_property_record.value());
    }
    }
    persistent_properties_loaded = true;
    property_set("ro.persistent_properties.ready", "true");
    property_set("ro.persistent_properties.ready", "true");
}
}


@@ -1020,37 +985,21 @@ void CreateSerializedPropertyInfo() {
    selinux_android_restorecon(kPropertyInfosPath, 0);
    selinux_android_restorecon(kPropertyInfosPath, 0);
}
}


static void PropertyServiceThread() {
void StartPropertyService(Epoll* epoll) {
    while (true) {
        handle_property_set_fd();
    }
}

void StartPropertyService(int* epoll_socket) {
    property_set("ro.property_service.version", "2");
    property_set("ro.property_service.version", "2");


    int sockets[2];
    if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
    if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockets) != 0) {
                                   false, 0666, 0, 0, {})) {
        PLOG(FATAL) << "Failed to socketpair() between property_service and init";
    }
    *epoll_socket = sockets[0];
    init_socket = sockets[1];

    if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC, false, 0666, 0, 0,
                                   {})) {
        property_set_fd = *result;
        property_set_fd = *result;
    } else {
    } else {
        LOG(FATAL) << "start_property_service socket creation failed: " << result.error();
        PLOG(FATAL) << "start_property_service socket creation failed: " << result.error();
    }
    }


    listen(property_set_fd, 8);
    listen(property_set_fd, 8);


    std::thread{PropertyServiceThread}.detach();
    if (auto result = epoll->RegisterHandler(property_set_fd, handle_property_set_fd); !result) {

        PLOG(FATAL) << result.error();
    property_set = [](const std::string& key, const std::string& value) -> uint32_t {
    }
        android::base::SetProperty(key, value);
        return 0;
    };
}
}


}  // namespace init
}  // namespace init
Loading