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