1 /*
2 * Copyright (C) 2020 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 #include <arpa/inet.h>
18 #include <cutils/sockets.h>
19 #include <errno.h>
20 #include <netinet/in.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <sys/socket.h>
25 #include <sys/system_properties.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28
29 #include <android-base/cmsg.h>
30 #include <android-base/logging.h>
31 #include <android-base/properties.h>
32 #include <android-base/scopeguard.h>
33 #include <android-base/strings.h>
34 #include <fs_mgr/file_wait.h>
35 #include <snapuserd/dm_user_block_server.h>
36 #include <snapuserd/snapuserd_client.h>
37 #include "snapuserd_server.h"
38 #include "user-space-merge/snapuserd_core.h"
39
40 namespace android {
41 namespace snapshot {
42
43 using namespace std::string_literals;
44
45 using android::base::borrowed_fd;
46 using android::base::unique_fd;
47
UserSnapshotServer()48 UserSnapshotServer::UserSnapshotServer() {
49 terminating_ = false;
50 handlers_ = std::make_unique<SnapshotHandlerManager>();
51 block_server_factory_ = std::make_unique<DmUserBlockServerFactory>();
52 }
53
~UserSnapshotServer()54 UserSnapshotServer::~UserSnapshotServer() {
55 // Close any client sockets that were added via AcceptClient().
56 for (size_t i = 1; i < watched_fds_.size(); i++) {
57 close(watched_fds_[i].fd);
58 }
59 }
60
GetDaemonStatus()61 std::string UserSnapshotServer::GetDaemonStatus() {
62 std::string msg = "";
63
64 if (IsTerminating())
65 msg = "passive";
66 else
67 msg = "active";
68
69 return msg;
70 }
71
Parsemsg(std::string const & msg,const char delim,std::vector<std::string> & out)72 void UserSnapshotServer::Parsemsg(std::string const& msg, const char delim,
73 std::vector<std::string>& out) {
74 std::stringstream ss(msg);
75 std::string s;
76
77 while (std::getline(ss, s, delim)) {
78 out.push_back(s);
79 }
80 }
81
ShutdownThreads()82 void UserSnapshotServer::ShutdownThreads() {
83 terminating_ = true;
84 handlers_->JoinAllThreads();
85 }
86
Sendmsg(android::base::borrowed_fd fd,const std::string & msg)87 bool UserSnapshotServer::Sendmsg(android::base::borrowed_fd fd, const std::string& msg) {
88 ssize_t ret = TEMP_FAILURE_RETRY(send(fd.get(), msg.data(), msg.size(), MSG_NOSIGNAL));
89 if (ret < 0) {
90 PLOG(ERROR) << "Snapuserd:server: send() failed";
91 return false;
92 }
93
94 if (ret < msg.size()) {
95 LOG(ERROR) << "Partial send; expected " << msg.size() << " bytes, sent " << ret;
96 return false;
97 }
98 return true;
99 }
100
Recv(android::base::borrowed_fd fd,std::string * data)101 bool UserSnapshotServer::Recv(android::base::borrowed_fd fd, std::string* data) {
102 char msg[kMaxPacketSize];
103 ssize_t rv = TEMP_FAILURE_RETRY(recv(fd.get(), msg, sizeof(msg), 0));
104 if (rv < 0) {
105 PLOG(ERROR) << "recv failed";
106 return false;
107 }
108 *data = std::string(msg, rv);
109 return true;
110 }
111
Receivemsg(android::base::borrowed_fd fd,const std::string & str)112 bool UserSnapshotServer::Receivemsg(android::base::borrowed_fd fd, const std::string& str) {
113 const char delim = ',';
114
115 std::vector<std::string> out;
116 Parsemsg(str, delim, out);
117
118 const auto& cmd = out[0];
119 if (cmd == "init") {
120 // Message format:
121 // init,<misc_name>,<cow_device_path>,<backing_device>,<base_path_merge>
122 //
123 // Reads the metadata and send the number of sectors
124 if (out.size() != 5) {
125 LOG(ERROR) << "Malformed init message, " << out.size() << " parts";
126 return Sendmsg(fd, "fail");
127 }
128
129 auto handler = AddHandler(out[1], out[2], out[3], out[4], std::nullopt);
130 if (!handler) {
131 return Sendmsg(fd, "fail");
132 }
133
134 auto num_sectors = handler->snapuserd()->GetNumSectors();
135 if (!num_sectors) {
136 return Sendmsg(fd, "fail");
137 }
138
139 auto retval = "success," + std::to_string(num_sectors);
140 return Sendmsg(fd, retval);
141 } else if (cmd == "start") {
142 // Message format:
143 // start,<misc_name>
144 //
145 // Start the new thread which binds to dm-user misc device
146 if (out.size() != 2) {
147 LOG(ERROR) << "Malformed start message, " << out.size() << " parts";
148 return Sendmsg(fd, "fail");
149 }
150
151 if (!handlers_->StartHandler(out[1])) {
152 return Sendmsg(fd, "fail");
153 }
154 return Sendmsg(fd, "success");
155 } else if (cmd == "stop") {
156 // Message format: stop
157 //
158 // Stop all the threads gracefully and then shutdown the
159 // main thread
160 SetTerminating();
161 ShutdownThreads();
162 return true;
163 } else if (cmd == "query") {
164 // Message format: query
165 //
166 // As part of transition, Second stage daemon will be
167 // created before terminating the first stage daemon. Hence,
168 // for a brief period client may have to distiguish between
169 // first stage daemon and second stage daemon.
170 //
171 // Second stage daemon is marked as active and hence will
172 // be ready to receive control message.
173 return Sendmsg(fd, GetDaemonStatus());
174 } else if (cmd == "delete") {
175 // Message format:
176 // delete,<misc_name>
177 if (out.size() != 2) {
178 LOG(ERROR) << "Malformed delete message, " << out.size() << " parts";
179 return Sendmsg(fd, "fail");
180 }
181 if (!handlers_->DeleteHandler(out[1])) {
182 return Sendmsg(fd, "fail");
183 }
184 return Sendmsg(fd, "success");
185 } else if (cmd == "detach") {
186 handlers_->TerminateMergeThreads();
187 terminating_ = true;
188 return true;
189 } else if (cmd == "supports") {
190 if (out.size() != 2) {
191 LOG(ERROR) << "Malformed supports message, " << out.size() << " parts";
192 return Sendmsg(fd, "fail");
193 }
194 if (out[1] == "second_stage_socket_handoff") {
195 return Sendmsg(fd, "success");
196 }
197 return Sendmsg(fd, "fail");
198 } else if (cmd == "initiate_merge") {
199 if (out.size() != 2) {
200 LOG(ERROR) << "Malformed initiate-merge message, " << out.size() << " parts";
201 return Sendmsg(fd, "fail");
202 }
203 if (out[0] == "initiate_merge") {
204 if (!handlers_->InitiateMerge(out[1])) {
205 return Sendmsg(fd, "fail");
206 }
207 return Sendmsg(fd, "success");
208 }
209 return Sendmsg(fd, "fail");
210 } else if (cmd == "merge_percent") {
211 double percentage = handlers_->GetMergePercentage();
212 return Sendmsg(fd, std::to_string(percentage));
213 } else if (cmd == "getstatus") {
214 // Message format:
215 // getstatus,<misc_name>
216 if (out.size() != 2) {
217 LOG(ERROR) << "Malformed delete message, " << out.size() << " parts";
218 return Sendmsg(fd, "snapshot-merge-failed");
219 }
220 auto status = handlers_->GetMergeStatus(out[1]);
221 if (status.empty()) {
222 return Sendmsg(fd, "snapshot-merge-failed");
223 }
224 return Sendmsg(fd, status);
225 } else if (cmd == "update-verify") {
226 if (!handlers_->GetVerificationStatus()) {
227 return Sendmsg(fd, "fail");
228 }
229 return Sendmsg(fd, "success");
230 } else {
231 LOG(ERROR) << "Received unknown message type from client";
232 Sendmsg(fd, "fail");
233 return false;
234 }
235 }
236
Start(const std::string & socketname)237 bool UserSnapshotServer::Start(const std::string& socketname) {
238 bool start_listening = true;
239
240 sockfd_.reset(android_get_control_socket(socketname.c_str()));
241 if (sockfd_ < 0) {
242 sockfd_.reset(socket_local_server(socketname.c_str(), ANDROID_SOCKET_NAMESPACE_RESERVED,
243 SOCK_STREAM));
244 if (sockfd_ < 0) {
245 PLOG(ERROR) << "Failed to create server socket " << socketname;
246 return false;
247 }
248 start_listening = false;
249 }
250 return StartWithSocket(start_listening);
251 }
252
StartWithSocket(bool start_listening)253 bool UserSnapshotServer::StartWithSocket(bool start_listening) {
254 if (start_listening && listen(sockfd_.get(), 4) < 0) {
255 PLOG(ERROR) << "listen socket failed";
256 return false;
257 }
258
259 AddWatchedFd(sockfd_, POLLIN);
260 is_socket_present_ = true;
261
262 // If started in first-stage init, the property service won't be online.
263 if (access("/dev/socket/property_service", F_OK) == 0) {
264 if (!android::base::SetProperty("snapuserd.ready", "true")) {
265 LOG(ERROR) << "Failed to set snapuserd.ready property";
266 return false;
267 }
268 }
269
270 LOG(DEBUG) << "Snapuserd server now accepting connections";
271 return true;
272 }
273
Run()274 bool UserSnapshotServer::Run() {
275 LOG(INFO) << "Now listening on snapuserd socket";
276
277 while (!IsTerminating()) {
278 int rv = TEMP_FAILURE_RETRY(poll(watched_fds_.data(), watched_fds_.size(), -1));
279 if (rv < 0) {
280 PLOG(ERROR) << "poll failed";
281 return false;
282 }
283 if (!rv) {
284 continue;
285 }
286
287 if (watched_fds_[0].revents) {
288 AcceptClient();
289 }
290
291 auto iter = watched_fds_.begin() + 1;
292 while (iter != watched_fds_.end()) {
293 if (iter->revents && !HandleClient(iter->fd, iter->revents)) {
294 close(iter->fd);
295 iter = watched_fds_.erase(iter);
296 } else {
297 iter++;
298 }
299 }
300 }
301
302 handlers_->JoinAllThreads();
303 return true;
304 }
305
AddWatchedFd(android::base::borrowed_fd fd,int events)306 void UserSnapshotServer::AddWatchedFd(android::base::borrowed_fd fd, int events) {
307 struct pollfd p = {};
308 p.fd = fd.get();
309 p.events = events;
310 watched_fds_.emplace_back(std::move(p));
311 }
312
AcceptClient()313 void UserSnapshotServer::AcceptClient() {
314 int fd = TEMP_FAILURE_RETRY(accept4(sockfd_.get(), nullptr, nullptr, SOCK_CLOEXEC));
315 if (fd < 0) {
316 PLOG(ERROR) << "accept4 failed";
317 return;
318 }
319
320 AddWatchedFd(fd, POLLIN);
321 }
322
HandleClient(android::base::borrowed_fd fd,int revents)323 bool UserSnapshotServer::HandleClient(android::base::borrowed_fd fd, int revents) {
324 std::string str;
325 if (!Recv(fd, &str)) {
326 return false;
327 }
328 if (str.empty() && (revents & POLLHUP)) {
329 LOG(DEBUG) << "Snapuserd client disconnected";
330 return false;
331 }
332 if (!Receivemsg(fd, str)) {
333 LOG(ERROR) << "Encountered error handling client message, revents: " << revents;
334 return false;
335 }
336 return true;
337 }
338
Interrupt()339 void UserSnapshotServer::Interrupt() {
340 // Force close the socket so poll() fails.
341 sockfd_ = {};
342 SetTerminating();
343 }
344
AddHandler(const std::string & misc_name,const std::string & cow_device_path,const std::string & backing_device,const std::string & base_path_merge,std::optional<uint32_t> num_worker_threads,const bool o_direct,uint32_t cow_op_merge_size)345 std::shared_ptr<HandlerThread> UserSnapshotServer::AddHandler(
346 const std::string& misc_name, const std::string& cow_device_path,
347 const std::string& backing_device, const std::string& base_path_merge,
348 std::optional<uint32_t> num_worker_threads, const bool o_direct,
349 uint32_t cow_op_merge_size) {
350 // We will need multiple worker threads only during
351 // device boot after OTA. For all other purposes,
352 // one thread is sufficient. We don't want to consume
353 // unnecessary memory especially during OTA install phase
354 // when daemon will be up during entire post install phase.
355 //
356 // During boot up, we need multiple threads primarily for
357 // update-verification.
358 if (!num_worker_threads.has_value()) {
359 num_worker_threads = kNumWorkerThreads;
360 }
361 if (is_socket_present_) {
362 num_worker_threads = 1;
363 }
364
365 if (android::base::EndsWith(misc_name, "-init") || is_socket_present_ ||
366 (access(kBootSnapshotsWithoutSlotSwitch, F_OK) == 0)) {
367 handlers_->DisableVerification();
368 }
369
370 auto opener = block_server_factory_->CreateOpener(misc_name);
371
372 return handlers_->AddHandler(misc_name, cow_device_path, backing_device, base_path_merge,
373 opener, num_worker_threads.value(), io_uring_enabled_, o_direct,
374 cow_op_merge_size);
375 }
376
WaitForSocket()377 bool UserSnapshotServer::WaitForSocket() {
378 auto scope_guard =
379 android::base::make_scope_guard([this]() -> void { handlers_->JoinAllThreads(); });
380
381 auto socket_path = ANDROID_SOCKET_DIR "/"s + kSnapuserdSocketProxy;
382
383 if (!android::fs_mgr::WaitForFile(socket_path, std::chrono::milliseconds::max())) {
384 LOG(ERROR)
385 << "Failed to wait for proxy socket, second-stage snapuserd will fail to connect";
386 return false;
387 }
388
389 // This initialization of system property is important. When daemon is
390 // launched post selinux transition (before init second stage),
391 // bionic libc initializes system property as part of __libc_init_common();
392 // however that initialization fails silently given that fact that we don't
393 // have /dev/__properties__ setup which is created at init second stage.
394 //
395 // At this point, we have the handlers setup and is safe to setup property.
396 __system_properties_init();
397
398 if (!android::base::WaitForProperty("snapuserd.proxy_ready", "true")) {
399 LOG(ERROR)
400 << "Failed to wait for proxy property, second-stage snapuserd will fail to connect";
401 return false;
402 }
403
404 unique_fd fd(socket_local_client(kSnapuserdSocketProxy, ANDROID_SOCKET_NAMESPACE_RESERVED,
405 SOCK_SEQPACKET));
406 if (fd < 0) {
407 PLOG(ERROR) << "Failed to connect to socket proxy";
408 return false;
409 }
410
411 char code[1];
412 std::vector<unique_fd> fds;
413 ssize_t rv = android::base::ReceiveFileDescriptorVector(fd, code, sizeof(code), 1, &fds);
414 if (rv < 0) {
415 PLOG(ERROR) << "Failed to receive server socket over proxy";
416 return false;
417 }
418 if (fds.empty()) {
419 LOG(ERROR) << "Expected at least one file descriptor from proxy";
420 return false;
421 }
422
423 // We don't care if the ACK is received.
424 code[0] = 'a';
425 if (TEMP_FAILURE_RETRY(send(fd, code, sizeof(code), MSG_NOSIGNAL)) < 0) {
426 PLOG(ERROR) << "Failed to send ACK to proxy";
427 return false;
428 }
429
430 sockfd_ = std::move(fds[0]);
431 if (!StartWithSocket(true)) {
432 return false;
433 }
434
435 return Run();
436 }
437
RunForSocketHandoff()438 bool UserSnapshotServer::RunForSocketHandoff() {
439 unique_fd proxy_fd(android_get_control_socket(kSnapuserdSocketProxy));
440 if (proxy_fd < 0) {
441 PLOG(FATAL) << "Proxy could not get android control socket " << kSnapuserdSocketProxy;
442 }
443 borrowed_fd server_fd(android_get_control_socket(kSnapuserdSocket));
444 if (server_fd < 0) {
445 PLOG(FATAL) << "Proxy could not get android control socket " << kSnapuserdSocket;
446 }
447
448 if (listen(proxy_fd.get(), 4) < 0) {
449 PLOG(FATAL) << "Proxy listen socket failed";
450 }
451
452 if (!android::base::SetProperty("snapuserd.proxy_ready", "true")) {
453 LOG(FATAL) << "Proxy failed to set ready property";
454 }
455
456 unique_fd client_fd(
457 TEMP_FAILURE_RETRY(accept4(proxy_fd.get(), nullptr, nullptr, SOCK_CLOEXEC)));
458 if (client_fd < 0) {
459 PLOG(FATAL) << "Proxy accept failed";
460 }
461
462 char code[1] = {'a'};
463 std::vector<int> fds = {server_fd.get()};
464 ssize_t rv = android::base::SendFileDescriptorVector(client_fd, code, sizeof(code), fds);
465 if (rv < 0) {
466 PLOG(FATAL) << "Proxy could not send file descriptor to snapuserd";
467 }
468 // Wait for an ACK - results don't matter, we just don't want to risk closing
469 // the proxy socket too early.
470 if (recv(client_fd, code, sizeof(code), 0) < 0) {
471 PLOG(FATAL) << "Proxy could not receive terminating code from snapuserd";
472 }
473 return true;
474 }
475
StartHandler(const std::string & misc_name)476 bool UserSnapshotServer::StartHandler(const std::string& misc_name) {
477 return handlers_->StartHandler(misc_name);
478 }
479
480 } // namespace snapshot
481 } // namespace android
482