Skip to content

Commit 457e28f

Browse files
author
Tom Cherry
committed
ueventd: require opt-in for modalias handling
Some devices have modules.alias and modules.dep for modprobe and other purposes but do not want to opt into ueventd auto loading their modules. Therefore we add a flag that can be added to ueventd configuration files to opt into this behavior. Bug: 111916071 Bug: 112048758 Test: check that modules are loaded with this opt-in Test: check that modules are not loaded without this opt-in Change-Id: Ifb281b273059b4671eea1ca5bc726c9e79f3adfb
1 parent 081b710 commit 457e28f

11 files changed

+122
-44
lines changed

init/devices.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ void DeviceHandler::HandleDevice(const std::string& action, const std::string& d
372372
}
373373
}
374374

375-
void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
375+
void DeviceHandler::HandleUevent(const Uevent& uevent) {
376376
if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") {
377377
FixupSysPermissions(uevent.path, uevent.subsystem);
378378
}
@@ -418,6 +418,10 @@ void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) {
418418
HandleDevice(uevent.action, devpath, block, uevent.major, uevent.minor, links);
419419
}
420420

421+
void DeviceHandler::ColdbootDone() {
422+
skip_restorecon_ = true;
423+
}
424+
421425
DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
422426
std::vector<SysfsPermissions> sysfs_permissions,
423427
std::vector<Subsystem> subsystems, std::set<std::string> boot_devices,

init/devices.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <selinux/label.h>
3030

3131
#include "uevent.h"
32+
#include "uevent_handler.h"
3233

3334
namespace android {
3435
namespace init {
@@ -105,19 +106,20 @@ class Subsystem {
105106
std::string dir_name_ = "/dev";
106107
};
107108

108-
class DeviceHandler {
109+
class DeviceHandler : public UeventHandler {
109110
public:
110111
friend class DeviceHandlerTester;
111112

112113
DeviceHandler();
113114
DeviceHandler(std::vector<Permissions> dev_permissions,
114115
std::vector<SysfsPermissions> sysfs_permissions, std::vector<Subsystem> subsystems,
115116
std::set<std::string> boot_devices, bool skip_restorecon);
117+
virtual ~DeviceHandler() = default;
116118

117-
void HandleDeviceEvent(const Uevent& uevent);
119+
void HandleUevent(const Uevent& uevent) override;
120+
void ColdbootDone() override;
118121

119122
std::vector<std::string> GetBlockDeviceSymlinks(const Uevent& uevent) const;
120-
void set_skip_restorecon(bool value) { skip_restorecon_ = value; }
121123

122124
private:
123125
bool FindPlatformDevice(std::string path, std::string* platform_device_path) const;

init/firmware_handler.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ using android::base::WriteFully;
3535
namespace android {
3636
namespace init {
3737

38-
std::vector<std::string> firmware_directories;
39-
4038
static void LoadFirmware(const Uevent& uevent, const std::string& root, int fw_fd, size_t fw_size,
4139
int loading_fd, int data_fd) {
4240
// Start transfer.
@@ -58,7 +56,10 @@ static bool IsBooting() {
5856
return access("/dev/.booting", F_OK) == 0;
5957
}
6058

61-
static void ProcessFirmwareEvent(const Uevent& uevent) {
59+
FirmwareHandler::FirmwareHandler(std::vector<std::string> firmware_directories)
60+
: firmware_directories_(std::move(firmware_directories)) {}
61+
62+
void FirmwareHandler::ProcessFirmwareEvent(const Uevent& uevent) {
6263
int booting = IsBooting();
6364

6465
LOG(INFO) << "firmware: loading '" << uevent.firmware << "' for '" << uevent.path << "'";
@@ -80,7 +81,7 @@ static void ProcessFirmwareEvent(const Uevent& uevent) {
8081
}
8182

8283
try_loading_again:
83-
for (const auto& firmware_directory : firmware_directories) {
84+
for (const auto& firmware_directory : firmware_directories_) {
8485
std::string file = firmware_directory + uevent.firmware;
8586
unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
8687
struct stat sb;
@@ -104,7 +105,7 @@ static void ProcessFirmwareEvent(const Uevent& uevent) {
104105
write(loading_fd, "-1", 2);
105106
}
106107

107-
void HandleFirmwareEvent(const Uevent& uevent) {
108+
void FirmwareHandler::HandleUevent(const Uevent& uevent) {
108109
if (uevent.subsystem != "firmware" || uevent.action != "add") return;
109110

110111
// Loading the firmware in a child means we can do that in parallel...

init/firmware_handler.h

+12-2
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,23 @@
2121
#include <vector>
2222

2323
#include "uevent.h"
24+
#include "uevent_handler.h"
2425

2526
namespace android {
2627
namespace init {
2728

28-
extern std::vector<std::string> firmware_directories;
29+
class FirmwareHandler : public UeventHandler {
30+
public:
31+
explicit FirmwareHandler(std::vector<std::string> firmware_directories);
32+
virtual ~FirmwareHandler() = default;
2933

30-
void HandleFirmwareEvent(const Uevent& uevent);
34+
void HandleUevent(const Uevent& uevent) override;
35+
36+
private:
37+
void ProcessFirmwareEvent(const Uevent& uevent);
38+
39+
std::vector<std::string> firmware_directories_;
40+
};
3141

3242
} // namespace init
3343
} // namespace android

init/first_stage_mount.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ bool FirstStageMount::InitRequiredDevices() {
206206
bool found = false;
207207
auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
208208
if (uevent.path == dm_path) {
209-
device_handler_->HandleDeviceEvent(uevent);
209+
device_handler_->HandleUevent(uevent);
210210
found = true;
211211
return ListenerAction::kStop;
212212
}
@@ -273,7 +273,7 @@ ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const
273273
lp_metadata_partition_ = links[0];
274274
}
275275
required_devices_partition_names_.erase(iter);
276-
device_handler_->HandleDeviceEvent(uevent);
276+
device_handler_->HandleUevent(uevent);
277277
if (required_devices_partition_names_.empty()) {
278278
return ListenerAction::kStop;
279279
} else {
@@ -310,7 +310,7 @@ bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
310310
auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) {
311311
if (uevent.device_name == device_name) {
312312
LOG(VERBOSE) << "Creating device-mapper device : " << dm_device;
313-
device_handler_->HandleDeviceEvent(uevent);
313+
device_handler_->HandleUevent(uevent);
314314
found = true;
315315
return ListenerAction::kStop;
316316
}

init/modalias_handler.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ Result<Success> ModaliasHandler::InsmodWithDeps(const std::string& module_name,
139139
return Insmod(dependencies[0], args);
140140
}
141141

142-
void ModaliasHandler::HandleModaliasEvent(const Uevent& uevent) {
142+
void ModaliasHandler::HandleUevent(const Uevent& uevent) {
143143
if (uevent.modalias.empty()) return;
144144

145145
for (const auto& [alias, module] : module_aliases_) {

init/modalias_handler.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,23 @@
1616

1717
#pragma once
1818

19-
#include "result.h"
20-
#include "uevent.h"
21-
2219
#include <string>
2320
#include <unordered_map>
2421
#include <vector>
2522

23+
#include "result.h"
24+
#include "uevent.h"
25+
#include "uevent_handler.h"
26+
2627
namespace android {
2728
namespace init {
2829

29-
class ModaliasHandler {
30+
class ModaliasHandler : public UeventHandler {
3031
public:
3132
ModaliasHandler();
32-
~ModaliasHandler(){};
33+
virtual ~ModaliasHandler() = default;
3334

34-
void HandleModaliasEvent(const Uevent& uevent);
35+
void HandleUevent(const Uevent& uevent) override;
3536

3637
private:
3738
Result<Success> InsmodWithDeps(const std::string& module_name, const std::string& args);

init/uevent_handler.h

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (C) 2018 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "uevent.h"
20+
21+
namespace android {
22+
namespace init {
23+
24+
class UeventHandler {
25+
public:
26+
virtual ~UeventHandler() = default;
27+
28+
virtual void HandleUevent(const Uevent& uevent) = 0;
29+
30+
virtual void ColdbootDone() {}
31+
};
32+
33+
} // namespace init
34+
} // namespace android

init/ueventd.cpp

+28-23
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "firmware_handler.h"
3939
#include "modalias_handler.h"
4040
#include "selinux.h"
41+
#include "uevent_handler.h"
4142
#include "uevent_listener.h"
4243
#include "ueventd_parser.h"
4344
#include "util.h"
@@ -107,11 +108,10 @@ namespace init {
107108

108109
class ColdBoot {
109110
public:
110-
ColdBoot(UeventListener& uevent_listener, DeviceHandler& device_handler,
111-
ModaliasHandler& modalias_handler)
111+
ColdBoot(UeventListener& uevent_listener,
112+
std::vector<std::unique_ptr<UeventHandler>>& uevent_handlers)
112113
: uevent_listener_(uevent_listener),
113-
device_handler_(device_handler),
114-
modalias_handler_(modalias_handler),
114+
uevent_handlers_(uevent_handlers),
115115
num_handler_subprocesses_(std::thread::hardware_concurrency() ?: 4) {}
116116

117117
void Run();
@@ -124,8 +124,7 @@ class ColdBoot {
124124
void WaitForSubProcesses();
125125

126126
UeventListener& uevent_listener_;
127-
DeviceHandler& device_handler_;
128-
ModaliasHandler& modalias_handler_;
127+
std::vector<std::unique_ptr<UeventHandler>>& uevent_handlers_;
129128

130129
unsigned int num_handler_subprocesses_;
131130
std::vector<Uevent> uevent_queue_;
@@ -136,16 +135,16 @@ class ColdBoot {
136135
void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_processes) {
137136
for (unsigned int i = process_num; i < uevent_queue_.size(); i += total_processes) {
138137
auto& uevent = uevent_queue_[i];
139-
device_handler_.HandleDeviceEvent(uevent);
140-
modalias_handler_.HandleModaliasEvent(uevent);
138+
139+
for (auto& uevent_handler : uevent_handlers_) {
140+
uevent_handler->HandleUevent(uevent);
141+
}
141142
}
142143
_exit(EXIT_SUCCESS);
143144
}
144145

145146
void ColdBoot::RegenerateUevents() {
146147
uevent_listener_.RegenerateUevents([this](const Uevent& uevent) {
147-
HandleFirmwareEvent(uevent);
148-
149148
uevent_queue_.emplace_back(std::move(uevent));
150149
return ListenerAction::kContinue;
151150
});
@@ -168,7 +167,6 @@ void ColdBoot::ForkSubProcesses() {
168167

169168
void ColdBoot::DoRestoreCon() {
170169
selinux_android_restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE);
171-
device_handler_.set_skip_restorecon(false);
172170
}
173171

174172
void ColdBoot::WaitForSubProcesses() {
@@ -234,8 +232,7 @@ int ueventd_main(int argc, char** argv) {
234232
SelinuxSetupKernelLogging();
235233
SelabelInitialize();
236234

237-
DeviceHandler device_handler;
238-
ModaliasHandler modalias_handler;
235+
std::vector<std::unique_ptr<UeventHandler>> uevent_handlers;
239236
UeventListener uevent_listener;
240237

241238
{
@@ -248,30 +245,38 @@ int ueventd_main(int argc, char** argv) {
248245
ParseConfig({"/ueventd.rc", "/vendor/ueventd.rc", "/odm/ueventd.rc",
249246
"/ueventd." + hardware + ".rc"});
250247

251-
device_handler = DeviceHandler{std::move(ueventd_configuration.dev_permissions),
252-
std::move(ueventd_configuration.sysfs_permissions),
253-
std::move(ueventd_configuration.subsystems),
254-
fs_mgr_get_boot_devices(), true};
248+
uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
249+
std::move(ueventd_configuration.dev_permissions),
250+
std::move(ueventd_configuration.sysfs_permissions),
251+
std::move(ueventd_configuration.subsystems), fs_mgr_get_boot_devices(), true));
252+
uevent_handlers.emplace_back(std::make_unique<FirmwareHandler>(
253+
std::move(ueventd_configuration.firmware_directories)));
255254

256-
firmware_directories = ueventd_configuration.firmware_directories;
255+
if (ueventd_configuration.enable_modalias_handling) {
256+
uevent_handlers.emplace_back(std::make_unique<ModaliasHandler>());
257+
}
257258
}
258259

259260
if (access(COLDBOOT_DONE, F_OK) != 0) {
260-
ColdBoot cold_boot(uevent_listener, device_handler, modalias_handler);
261+
ColdBoot cold_boot(uevent_listener, uevent_handlers);
261262
cold_boot.Run();
262263
}
263264

265+
for (auto& uevent_handler : uevent_handlers) {
266+
uevent_handler->ColdbootDone();
267+
}
268+
264269
// We use waitpid() in ColdBoot, so we can't ignore SIGCHLD until now.
265270
signal(SIGCHLD, SIG_IGN);
266271
// Reap and pending children that exited between the last call to waitpid() and setting SIG_IGN
267272
// for SIGCHLD above.
268273
while (waitpid(-1, nullptr, WNOHANG) > 0) {
269274
}
270275

271-
uevent_listener.Poll([&device_handler, &modalias_handler](const Uevent& uevent) {
272-
HandleFirmwareEvent(uevent);
273-
modalias_handler.HandleModaliasEvent(uevent);
274-
device_handler.HandleDeviceEvent(uevent);
276+
uevent_listener.Poll([&uevent_handlers](const Uevent& uevent) {
277+
for (auto& uevent_handler : uevent_handlers) {
278+
uevent_handler->HandleUevent(uevent);
279+
}
275280
return ListenerAction::kContinue;
276281
});
277282

init/ueventd_parser.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,23 @@ Result<Success> ParseFirmwareDirectoriesLine(std::vector<std::string>&& args,
8484
return Success();
8585
}
8686

87+
Result<Success> ParseModaliasHandlingLine(std::vector<std::string>&& args,
88+
bool* enable_modalias_handling) {
89+
if (args.size() != 2) {
90+
return Error() << "modalias_handling lines take exactly one parameter";
91+
}
92+
93+
if (args[1] == "enabled") {
94+
*enable_modalias_handling = true;
95+
} else if (args[1] == "disabled") {
96+
*enable_modalias_handling = false;
97+
} else {
98+
return Error() << "modalias_handling takes either 'enabled' or 'disabled' as a parameter";
99+
}
100+
101+
return Success();
102+
}
103+
87104
class SubsystemParser : public SectionParser {
88105
public:
89106
SubsystemParser(std::vector<Subsystem>* subsystems) : subsystems_(subsystems) {}
@@ -182,6 +199,9 @@ UeventdConfiguration ParseConfig(const std::vector<std::string>& configs) {
182199
parser.AddSingleLineParser("firmware_directories",
183200
std::bind(ParseFirmwareDirectoriesLine, _1,
184201
&ueventd_configuration.firmware_directories));
202+
parser.AddSingleLineParser("modalias_handling",
203+
std::bind(ParseModaliasHandlingLine, _1,
204+
&ueventd_configuration.enable_modalias_handling));
185205

186206
for (const auto& config : configs) {
187207
parser.ParseConfig(config);

init/ueventd_parser.h

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct UeventdConfiguration {
3030
std::vector<SysfsPermissions> sysfs_permissions;
3131
std::vector<Permissions> dev_permissions;
3232
std::vector<std::string> firmware_directories;
33+
bool enable_modalias_handling = false;
3334
};
3435

3536
UeventdConfiguration ParseConfig(const std::vector<std::string>& configs);

0 commit comments

Comments
 (0)