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