Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions init/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ static Result<std::string> ComputeContextFromExecutable(const std::string& servi
return computed_context;
}

static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) {
static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop,
bool disable_hardened_malloc) {
std::vector<std::string> expanded_args;
std::vector<char*> c_strings;

Expand All @@ -134,6 +135,22 @@ static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigsto
kill(getpid(), SIGSTOP);
}


if (disable_hardened_malloc) {
#if defined(__BIONIC__)
if (setenv("DISABLE_HARDENED_MALLOC", "1", 1) != 0) {
LOG(ERROR) << "setenv(DISABLE_HARDENED_MALLOC) failed: " << strerror(errno);
}
#if defined(__aarch64__)
const int FLAG_COMPAT_VA_39_BIT = 1 << 30;
execveat(-1, c_strings[0], c_strings.data(), environ, FLAG_COMPAT_VA_39_BIT);
LOG(ERROR) << "execveat with FLAG_COMPAT_VA_39_BIT failed for " << c_strings[0] << ": " << strerror(errno);
#endif // defined(__aarch64__)
#else
LOG(ERROR) << "ignored disable_hardened_malloc option in non-bionic environment";
#endif // defined(__BIONIC__)
}

return execv(c_strings[0], c_strings.data()) == 0;
}

Expand Down Expand Up @@ -578,7 +595,7 @@ void Service::RunService(const std::vector<Descriptor>& descriptors,
// priority. Aborts on failure.
SetProcessAttributesAndCaps(std::move(setsid_finished));

if (!ExpandArgsAndExecv(args_, sigstop_)) {
if (!ExpandArgsAndExecv(args_, sigstop_, disable_hardened_malloc_)) {
PLOG(ERROR) << "cannot execv('" << args_[0]
<< "'). See the 'Debugging init' section of init's README.md for tips";
}
Expand Down
2 changes: 2 additions & 0 deletions init/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ class Service {

bool sigstop_ = false;

bool disable_hardened_malloc_ = false;

const std::chrono::seconds default_restart_period_ = 5s;
std::chrono::seconds restart_period_ = default_restart_period_;
std::optional<std::chrono::seconds> timeout_period_;
Expand Down
6 changes: 6 additions & 0 deletions init/service_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,11 @@ Result<void> ServiceParser::ParseSigstop(std::vector<std::string>&& args) {
return {};
}

Result<void> ServiceParser::ParseDisableHardenedMalloc(std::vector<std::string>&& args) {
service_->disable_hardened_malloc_ = true;
return {};
}

Result<void> ServiceParser::ParseSetenv(std::vector<std::string>&& args) {
service_->environment_vars_.emplace_back(std::move(args[1]), std::move(args[2]));
return {};
Expand Down Expand Up @@ -612,6 +617,7 @@ const KeywordMap<ServiceParser::OptionParser>& ServiceParser::GetParserMap() con
{"shared_kallsyms", {0, 0, &ServiceParser::ParseSharedKallsyms}},
{"shutdown", {1, 1, &ServiceParser::ParseShutdown}},
{"sigstop", {0, 0, &ServiceParser::ParseSigstop}},
{"disable_hardened_malloc", {0, 0, &ServiceParser::ParseDisableHardenedMalloc}},
{"socket", {3, 6, &ServiceParser::ParseSocket}},
{"stdio_to_kmsg", {0, 0, &ServiceParser::ParseStdioToKmsg}},
{"task_profiles", {1, kMax, &ServiceParser::ParseTaskProfiles}},
Expand Down
1 change: 1 addition & 0 deletions init/service_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class ServiceParser : public SectionParser {
Result<void> ParseSharedKallsyms(std::vector<std::string>&& args);
Result<void> ParseShutdown(std::vector<std::string>&& args);
Result<void> ParseSigstop(std::vector<std::string>&& args);
Result<void> ParseDisableHardenedMalloc(std::vector<std::string>&& args);
Result<void> ParseSocket(std::vector<std::string>&& args);
Result<void> ParseStdioToKmsg(std::vector<std::string>&& args);
Result<void> ParseTaskProfiles(std::vector<std::string>&& args);
Expand Down
7 changes: 7 additions & 0 deletions rootdir/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ prebuilt_etc {
name: "init.zygote64.rc",
src: "init.zygote64.rc",
sub_dir: "init/hw",
required: ["init.zygote64_compat.rc"],
}

prebuilt_etc {
name: "init.zygote64_compat.rc",
src: "init.zygote64_compat.rc",
sub_dir: "init/hw",
}

prebuilt_etc {
Expand Down
1 change: 1 addition & 0 deletions rootdir/init.rc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /system/etc/init/hw/init.usb.configfs.rc
import /system/etc/init/hw/init.${ro.zygote}.rc
import /system/etc/init/hw/init.zygote64_compat.rc

# Cgroups are mounted right before early-init using list from /etc/cgroups.json
on early-init
Expand Down
14 changes: 14 additions & 0 deletions rootdir/init.zygote64_compat.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
service zygote_compat /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_compat
disable_hardened_malloc
class main
priority -20
user root
group root readproc reserved_disk
rlimit nofile 32768 262144
socket zygote_compat stream 660 root system
socket usap_pool_compat stream 660 root system
task_profiles ProcessCapacityHigh MaxPerformance
disabled

on property:sys.start_compat_zygote=1
start zygote_compat
5 changes: 5 additions & 0 deletions toolbox/start.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ static void ControlDefaultServices(bool start) {
services.emplace_back("zygote_secondary");
}

if (!start) {
// compat zygote is started on-demand
services.emplace_back("zygote_compat");
}

if (start) {
for (const auto& service : services) {
ControlService(true, service);
Expand Down