// If we're trying to set "sys.powerctl" from a privileged process, use the special // socket. Because this socket is only accessible to privileged processes, it can't // be DoSed directly by malicious apps. (The shell user should be able to reboot, // though, so we don't just always use the special socket for "sys.powerctl".) // See b/262237198 for context constchar* socket = property_service_socket; if (strcmp(name, "sys.powerctl") == 0 &&
access(property_service_for_system_socket, W_OK) == 0) {
socket = property_service_for_system_socket;
}
constint num_bytes = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg), 0)); if (num_bytes == sizeof(prop_msg)) { // We successfully wrote to the property server but now we // wait for the property server to finish its work. It // acknowledges its completion by closing the socket so we // poll here (on nothing), waiting for the socket to close. // If you 'adb shell setprop foo bar' you'll see the POLLHUP // once the socket closes. Out of paranoia we cap our poll // at 250 ms.
pollfd pollfds[1];
pollfds[0].fd = s;
pollfds[0].events = 0; constint poll_result = TEMP_FAILURE_RETRY(poll(pollfds, 1, 250/* ms */)); if (poll_result == 1 && (pollfds[0].revents & POLLHUP) != 0) {
result = 0;
} else { // Ignore the timeout and treat it like a success anyway. // The init process is single-threaded and its property // service is sometimes slow to respond (perhaps it's off // starting a child process or something) and thus this // times out and the caller thinks it failed, even though // it's still getting around to it. So we fake it here, // mostly for ctl.* properties, but we do try and wait 250 // ms so callers who do read-after-write can reliably see // what they've written. Most of the time.
async_safe_format_log(ANDROID_LOG_WARN, "libc", "Property service has timed out while trying to set \"%s\" to \"%s\"",
msg->name, msg->value);
result = 0;
}
}
staticvoid detect_protocol_version() { char value[PROP_VALUE_MAX]; if (__system_property_get(kServiceVersionPropertyName, value) == 0) {
g_propservice_protocol_version = kProtocolVersion1;
async_safe_format_log(ANDROID_LOG_WARN, "libc", "Using old property service protocol (\"%s\" is not set)",
kServiceVersionPropertyName);
} else {
uint32_t version = static_cast<uint32_t>(atoll(value)); if (version >= kProtocolVersion2) {
g_propservice_protocol_version = kProtocolVersion2;
} else {
async_safe_format_log(ANDROID_LOG_WARN, "libc", "Using old property service protocol (\"%s\"=\"%s\")",
kServiceVersionPropertyName, value);
g_propservice_protocol_version = kProtocolVersion1;
}
}
}
staticconstchar* __prop_error_to_string(int error) { switch (error) { case PROP_ERROR_READ_CMD: return"PROP_ERROR_READ_CMD"; case PROP_ERROR_READ_DATA: return"PROP_ERROR_READ_DATA"; case PROP_ERROR_READ_ONLY_PROPERTY: return"PROP_ERROR_READ_ONLY_PROPERTY"; case PROP_ERROR_INVALID_NAME: return"PROP_ERROR_INVALID_NAME"; case PROP_ERROR_INVALID_VALUE: return"PROP_ERROR_INVALID_VALUE"; case PROP_ERROR_PERMISSION_DENIED: return"PROP_ERROR_PERMISSION_DENIED"; case PROP_ERROR_INVALID_CMD: return"PROP_ERROR_INVALID_CMD"; case PROP_ERROR_HANDLE_CONTROL_MESSAGE: return"PROP_ERROR_HANDLE_CONTROL_MESSAGE"; case PROP_ERROR_SET_FAILED: return"PROP_ERROR_SET_FAILED";
} return"<unknown>";
}
__BIONIC_WEAK_FOR_NATIVE_BRIDGE int __system_property_set(constchar* key, constchar* value) { if (key == nullptr) return -1; if (value == nullptr) value = "";
if (g_propservice_protocol_version == 0) {
detect_protocol_version();
}
if (g_propservice_protocol_version == kProtocolVersion1) { // Old protocol does not support long names or values if (strlen(key) >= PROP_NAME_MAX) return -1; if (strlen(value) >= PROP_VALUE_MAX) return -1;
return send_prop_msg(&msg);
} else { // New protocol only allows long values for ro. properties only. if (strlen(value) >= PROP_VALUE_MAX && strncmp(key, "ro.", 3) != 0) return -1; // Use proper protocol
PropertyServiceConnection connection(key); if (!connection.IsValid()) {
errno = connection.GetLastError();
async_safe_format_log(ANDROID_LOG_WARN, "libc", "Unable to set property \"%s\" to \"%s\": connection failed: %m", key,
value); return -1;
}
SocketWriter writer(&connection); if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) {
errno = connection.GetLastError();
async_safe_format_log(ANDROID_LOG_WARN, "libc", "Unable to set property \"%s\" to \"%s\": write failed: %m", key,
value); return -1;
}
int result = -1; if (!connection.RecvInt32(&result)) {
errno = connection.GetLastError();
async_safe_format_log(ANDROID_LOG_WARN, "libc", "Unable to set property \"%s\" to \"%s\": recv failed: %m", key, value); return -1;
}
if (result != PROP_SUCCESS) {
async_safe_format_log(ANDROID_LOG_WARN, "libc", "Unable to set property \"%s\" to \"%s\": %s (0x%x)", key, value,
__prop_error_to_string(result), result); return -1;
}
return0;
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.