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

Commit 02de9123 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4562879 from ba6a6066 to pi-release

Change-Id: I695d9e2e0bdfa1a1c97f456ea508e1ad0a37f900
parents 0f220a7c ba6a6066
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ cc_library_static {
        "libbacktrace",
        "libunwind",
        "libunwindstack",
        "libdexfile",
        "liblzma",
        "libcutils",
    ],
+6 −20
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@
#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
#define FAKE_BATTERY_CAPACITY 42
#define FAKE_BATTERY_TEMPERATURE 424
#define ALWAYS_PLUGGED_CAPACITY 100
#define MILLION 1.0e6
#define DEFAULT_VBUS_VOLTAGE 5000000

@@ -81,8 +80,11 @@ static void initBatteryProperties(BatteryProperties* props) {
    props->batteryTechnology.clear();
}

BatteryMonitor::BatteryMonitor() : mHealthdConfig(nullptr), mBatteryDevicePresent(false),
    mAlwaysPluggedDevice(false), mBatteryFixedCapacity(0), mBatteryFixedTemperature(0) {
BatteryMonitor::BatteryMonitor()
    : mHealthdConfig(nullptr),
      mBatteryDevicePresent(false),
      mBatteryFixedCapacity(0),
      mBatteryFixedTemperature(0) {
    initBatteryProperties(&props);
}

@@ -227,15 +229,6 @@ bool BatteryMonitor::update(void) {
        mBatteryFixedTemperature :
        getIntField(mHealthdConfig->batteryTemperaturePath);

    // For devices which do not have battery and are always plugged
    // into power souce.
    if (mAlwaysPluggedDevice) {
        props.chargerAcOnline = true;
        props.batteryPresent = true;
        props.batteryStatus = BATTERY_STATUS_CHARGING;
        props.batteryHealth = BATTERY_HEALTH_GOOD;
    }

    std::string buf;

    if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
@@ -409,11 +402,7 @@ status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
        break;

    case BATTERY_PROP_BATTERY_STATUS:
        if (mAlwaysPluggedDevice) {
            val->valueInt64 = BATTERY_STATUS_CHARGING;
        } else {
        val->valueInt64 = getChargeStatus();
        }
        ret = NO_ERROR;
        break;

@@ -632,9 +621,6 @@ void BatteryMonitor::init(struct healthd_config *hc) {
        KLOG_WARNING(LOG_TAG, "No battery devices found\n");
        hc->periodic_chores_interval_fast = -1;
        hc->periodic_chores_interval_slow = -1;
        mBatteryFixedCapacity = ALWAYS_PLUGGED_CAPACITY;
        mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
        mAlwaysPluggedDevice = true;
    } else {
        if (mHealthdConfig->batteryStatusPath.isEmpty())
            KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
+0 −1
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ class BatteryMonitor {
    struct healthd_config *mHealthdConfig;
    Vector<String8> mChargerNames;
    bool mBatteryDevicePresent;
    bool mAlwaysPluggedDevice;
    int mBatteryFixedCapacity;
    int mBatteryFixedTemperature;
    struct BatteryProperties props;
+1 −3
Original line number Diff line number Diff line
@@ -1039,9 +1039,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
        {"restorecon_recursive",    {1,     kMax, {true,   do_restorecon_recursive}}},
        {"rm",                      {1,     1,    {true,   do_rm}}},
        {"rmdir",                   {1,     1,    {true,   do_rmdir}}},
        //  TODO: setprop should be run in the subcontext, but property service needs to be split
        //        out from init before that is possible.
        {"setprop",                 {2,     2,    {false,  do_setprop}}},
        {"setprop",                 {2,     2,    {true,   do_setprop}}},
        {"setrlimit",               {3,     3,    {false,  do_setrlimit}}},
        {"start",                   {1,     1,    {false,  do_start}}},
        {"stop",                    {1,     1,    {false,  do_stop}}},
+186 −179
Original line number Diff line number Diff line
@@ -84,6 +84,10 @@ static int property_set_fd = -1;

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 property_init() {
@@ -97,7 +101,7 @@ void property_init() {
    }
}
static bool CheckMacPerms(const std::string& name, const char* target_context,
                          const char* source_context, struct ucred* cr) {
                          const char* source_context, const ucred& cr) {
    if (!target_context || !source_context) {
        return false;
    }
@@ -105,7 +109,7 @@ static bool CheckMacPerms(const std::string& name, const char* target_context,
    property_audit_data audit_data;

    audit_data.name = name.c_str();
    audit_data.cr = cr;
    audit_data.cr = &cr;

    bool has_access = (selinux_check_access(source_context, target_context, "property_service",
                                            "set", &audit_data) == 0);
@@ -257,7 +261,7 @@ static int RestoreconRecursiveAsync(const std::string& name, const std::string&
    return selinux_android_restorecon(value.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE);
}

uint32_t property_set(const std::string& name, const std::string& value) {
uint32_t PropertySet(const std::string& name, const std::string& value) {
    if (name == "selinux.restorecon_recursive") {
        return PropertySetAsync(name, value, RestoreconRecursiveAsync);
    }
@@ -265,14 +269,29 @@ uint32_t property_set(const std::string& name, const std::string& value) {
    return PropertySetImpl(name, value);
}

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

    const char* type = nullptr;
    property_info_area->GetPropertyInfo(name.c_str(), nullptr, &type);

    if (type == nullptr || !CheckType(type, value)) {
        LOG(ERROR) << "property_set: name: '" << name << "' type check failed, type: '"
                   << (type ?: "(null)") << "' value: '" << value << "'";
        return PROP_ERROR_INVALID_VALUE;
    }

    return PropertySet(name, value);
}

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

  ~SocketConnection() {
    close(socket_);
  }
    ~SocketConnection() { close(socket_); }

    bool RecvUint32(uint32_t* value, uint32_t* timeout_ms) {
        return RecvFully(value, sizeof(*value), timeout_ms);
@@ -314,12 +333,16 @@ class SocketConnection {
        return result == sizeof(value);
    }

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

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

    std::string source_context() const {
        char* source_context = nullptr;
        getpeercon(socket_, &source_context);
        std::string result = source_context;
        freecon(source_context);
        return result;
    }

  private:
@@ -332,7 +355,8 @@ class SocketConnection {
            auto start_time = std::chrono::steady_clock::now();
            int nr = poll(ufds, 1, *timeout_ms);
            auto now = std::chrono::steady_clock::now();
        auto time_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
            auto time_elapsed =
                std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
            uint64_t millis = time_elapsed.count();
            *timeout_ms = (millis > *timeout_ms) ? 0 : *timeout_ms - millis;

@@ -346,7 +370,8 @@ class SocketConnection {
            }

            if (nr < 0 && errno != EINTR) {
        PLOG(ERROR) << "sys_prop: error waiting for uid " << cred_.uid << " to send property message";
                PLOG(ERROR) << "sys_prop: error waiting for uid " << cred_.uid
                            << " to send property message";
                return false;
            } else {  // errno == EINTR
                // Timer rounds milliseconds down in case of EINTR we want it to be rounded up
@@ -357,7 +382,8 @@ class SocketConnection {
            }
        }

    LOG(ERROR) << "sys_prop: timeout waiting for uid " << cred_.uid << " to send property message.";
        LOG(ERROR) << "sys_prop: timeout waiting for uid " << cred_.uid
                   << " to send property message.";
        return false;
    }

@@ -382,70 +408,53 @@ class SocketConnection {
    }

    int socket_;
  struct ucred cred_;
    ucred cred_;

    DISALLOW_IMPLICIT_CONSTRUCTORS(SocketConnection);
};

static void handle_property_set(SocketConnection& socket,
                                const std::string& name,
                                const std::string& value,
                                bool legacy_protocol) {
  const char* cmd_name = legacy_protocol ? "PROP_MSG_SETPROP" : "PROP_MSG_SETPROP2";
// This returns one of the enum of PROP_SUCCESS or PROP_ERROR*.
uint32_t HandlePropertySet(const std::string& name, const std::string& value,
                           const std::string& source_context, const ucred& cr) {
    if (!is_legal_property_name(name)) {
    LOG(ERROR) << "sys_prop(" << cmd_name << "): illegal property name \"" << name << "\"";
    socket.SendUint32(PROP_ERROR_INVALID_NAME);
    return;
        LOG(ERROR) << "PropertySet: illegal property name \"" << name << "\"";
        return PROP_ERROR_INVALID_NAME;
    }

  struct ucred cr = socket.cred();
  char* source_ctx = nullptr;
  getpeercon(socket.socket(), &source_ctx);
  std::string source_context = source_ctx;
  freecon(source_ctx);

    if (StartsWith(name, "ctl.")) {
      // ctl. properties have their name ctl.<action> and their value is the name of the service to
      // apply that action to.  Permissions for these actions are based on the service, so we must
      // create a fake name of ctl.<service> to check permissions.
        // ctl. properties have their name ctl.<action> and their value is the name of the service
        // to apply that action to.  Permissions for these actions are based on the service, so we
        // must create a fake name of ctl.<service> to check permissions.
        auto control_string = "ctl." + value;
        const char* target_context = nullptr;
        const char* type = nullptr;
        property_info_area->GetPropertyInfo(control_string.c_str(), &target_context, &type);
      if (!CheckMacPerms(control_string, target_context, source_context.c_str(), &cr)) {
          LOG(ERROR) << "sys_prop(" << cmd_name << "): Unable to " << (name.c_str() + 4)
                     << " service ctl [" << value << "]"
        if (!CheckMacPerms(control_string, target_context, source_context.c_str(), cr)) {
            LOG(ERROR) << "PropertySet: Unable to " << (name.c_str() + 4) << " service ctl ["
                       << value << "]"
                       << " uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid;
          if (!legacy_protocol) {
              socket.SendUint32(PROP_ERROR_HANDLE_CONTROL_MESSAGE);
          }
          return;
            return PROP_ERROR_HANDLE_CONTROL_MESSAGE;
        }

        handle_control_message(name.c_str() + 4, value.c_str());
      if (!legacy_protocol) {
          socket.SendUint32(PROP_SUCCESS);
        return PROP_SUCCESS;
    }
  } else {

    const char* target_context = nullptr;
    const char* type = nullptr;
    property_info_area->GetPropertyInfo(name.c_str(), &target_context, &type);
      if (!CheckMacPerms(name, target_context, source_context.c_str(), &cr)) {
          LOG(ERROR) << "sys_prop(" << cmd_name << "): permission denied uid:" << cr.uid
                     << " name:" << name;
          if (!legacy_protocol) {
              socket.SendUint32(PROP_ERROR_PERMISSION_DENIED);
          }
          return;

    if (!CheckMacPerms(name, target_context, source_context.c_str(), cr)) {
        LOG(ERROR) << "PropertySet: permission denied uid:" << cr.uid << " name:" << name;
        return PROP_ERROR_PERMISSION_DENIED;
    }

    if (type == nullptr || !CheckType(type, value)) {
          LOG(ERROR) << "sys_prop(" << cmd_name << "): type check failed, type: '"
        LOG(ERROR) << "PropertySet: name: '" << name << "' type check failed, type: '"
                   << (type ?: "(null)") << "' value: '" << value << "'";
          if (!legacy_protocol) {
              socket.SendUint32(PROP_ERROR_INVALID_VALUE);
          }
          return;
        return PROP_ERROR_INVALID_VALUE;
    }

    // sys.powerctl is a special property that is used to make the device reboot.  We want to log
    // any process that sets this property to be able to accurately blame the cause of a shutdown.
    if (name == "sys.powerctl") {
@@ -453,18 +462,15 @@ static void handle_property_set(SocketConnection& socket,
        std::string process_cmdline;
        std::string process_log_string;
        if (ReadFileToString(cmdline_path, &process_cmdline)) {
              // Since cmdline is null deliminated, .c_str() conveniently gives us just the process path.
            // Since cmdline is null deliminated, .c_str() conveniently gives us just the process
            // path.
            process_log_string = StringPrintf(" (%s)", process_cmdline.c_str());
        }
        LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid
                  << process_log_string;
    }

      uint32_t result = property_set(name, value);
      if (!legacy_protocol) {
          socket.SendUint32(result);
      }
  }
    return PropertySet(name, value);
}

static void handle_property_set_fd() {
@@ -475,7 +481,7 @@ static void handle_property_set_fd() {
        return;
    }

    struct ucred cr;
    ucred cr;
    socklen_t cr_size = sizeof(cr);
    if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) {
        close(s);
@@ -507,7 +513,7 @@ static void handle_property_set_fd() {
        prop_name[PROP_NAME_MAX-1] = 0;
        prop_value[PROP_VALUE_MAX-1] = 0;

        handle_property_set(socket, prop_value, prop_value, true);
        HandlePropertySet(prop_value, prop_value, socket.source_context(), socket.cred());
        break;
      }

@@ -521,7 +527,8 @@ static void handle_property_set_fd() {
          return;
        }

        handle_property_set(socket, name, value, false);
        auto result = HandlePropertySet(name, value, socket.source_context(), socket.cred());
        socket.SendUint32(result);
        break;
      }

Loading