1 /*
2  * Copyright (C) 2016 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 #include <cutils/properties.h>
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <inttypes.h>
20 #include <libgen.h>
21 #include <linux/fs.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/stat.h>
26 #include <sys/syscall.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 
30 #include "checkpoint_handling.h"
31 #include "ipc.h"
32 #include "log.h"
33 #include "storage.h"
34 #include "watchdog.h"
35 
36 #define FD_TBL_SIZE 64
37 #define MAX_READ_SIZE 4096
38 
39 #define ALTERNATE_DATA_DIR "alternate/"
40 
41 /* Maximum file size for filesystem backed storage (i.e. not block dev backed storage) */
42 #define MAX_FILE_SIZE (0x10000000000)
43 
44 enum sync_state {
45     SS_UNUSED = -1,
46     SS_CLEAN =  0,
47     SS_DIRTY =  1,
48 };
49 
50 static const char *ssdir_name;
51 
52 /*
53  * Property set to 1 after we have opened a file under ssdir_name. The backing
54  * files for both TD and TDP are currently located under /data/vendor/ss and can
55  * only be opened once userdata is mounted. This storageproxyd service is
56  * restarted when userdata is available, which causes the Trusty storage service
57  * to reconnect and attempt to open the backing files for TD and TDP. Once we
58  * set this property, other users can expect that the Trusty storage service
59  * ports will be available (although they may block if still being initialized),
60  * and connections will not be reset after this point (assuming the
61  * storageproxyd service stays running).
62  */
63 #define FS_READY_PROPERTY "ro.vendor.trusty.storage.fs_ready"
64 
65 /* has FS_READY_PROPERTY been set? */
66 static bool fs_ready_initialized = false;
67 
68 static enum sync_state fs_state;
69 static enum sync_state fd_state[FD_TBL_SIZE];
70 
71 static bool alternate_mode;
72 
73 static struct {
74    struct storage_file_read_resp hdr;
75    uint8_t data[MAX_READ_SIZE];
76 }  read_rsp;
77 
insert_fd(int open_flags,int fd)78 static uint32_t insert_fd(int open_flags, int fd)
79 {
80     uint32_t handle = fd;
81 
82     if (handle < FD_TBL_SIZE) {
83             fd_state[fd] = SS_CLEAN; /* fd clean */
84             if (open_flags & O_TRUNC) {
85                 fd_state[fd] = SS_DIRTY;  /* set fd dirty */
86             }
87     } else {
88             ALOGW("%s: untracked fd %u\n", __func__, fd);
89             if (open_flags & (O_TRUNC | O_CREAT)) {
90                 fs_state = SS_DIRTY;
91             }
92     }
93     return handle;
94 }
95 
lookup_fd(uint32_t handle,bool dirty)96 static int lookup_fd(uint32_t handle, bool dirty)
97 {
98     if (dirty) {
99         if (handle < FD_TBL_SIZE) {
100             fd_state[handle] = SS_DIRTY;
101         } else {
102             fs_state = SS_DIRTY;
103         }
104     }
105     return handle;
106 }
107 
remove_fd(uint32_t handle)108 static int remove_fd(uint32_t handle)
109 {
110     if (handle < FD_TBL_SIZE) {
111         fd_state[handle] = SS_UNUSED; /* set to uninstalled */
112     }
113     return handle;
114 }
115 
translate_errno(int error)116 static enum storage_err translate_errno(int error)
117 {
118     enum storage_err result;
119     switch (error) {
120     case 0:
121         result = STORAGE_NO_ERROR;
122         break;
123     case EBADF:
124     case EINVAL:
125     case ENOTDIR:
126     case EISDIR:
127     case ENAMETOOLONG:
128         result = STORAGE_ERR_NOT_VALID;
129         break;
130     case ENOENT:
131         result = STORAGE_ERR_NOT_FOUND;
132         break;
133     case EEXIST:
134         result = STORAGE_ERR_EXIST;
135         break;
136     case EPERM:
137     case EACCES:
138         result = STORAGE_ERR_ACCESS;
139         break;
140     default:
141         result = STORAGE_ERR_GENERIC;
142         break;
143     }
144 
145     return result;
146 }
147 
write_with_retry(int fd,const void * buf_,size_t size,off_t offset)148 static ssize_t write_with_retry(int fd, const void *buf_, size_t size, off_t offset)
149 {
150     ssize_t rc;
151     const uint8_t *buf = buf_;
152 
153     while (size > 0) {
154         rc = TEMP_FAILURE_RETRY(pwrite(fd, buf, size, offset));
155         if (rc < 0)
156             return rc;
157         size -= rc;
158         buf += rc;
159         offset += rc;
160     }
161     return 0;
162 }
163 
read_with_retry(int fd,void * buf_,size_t size,off_t offset)164 static ssize_t read_with_retry(int fd, void *buf_, size_t size, off_t offset)
165 {
166     ssize_t rc;
167     size_t  rcnt = 0;
168     uint8_t *buf = buf_;
169 
170     while (size > 0) {
171         rc = TEMP_FAILURE_RETRY(pread(fd, buf, size, offset));
172         if (rc < 0)
173             return rc;
174         if (rc == 0)
175             break;
176         size -= rc;
177         buf += rc;
178         offset += rc;
179         rcnt += rc;
180     }
181     return rcnt;
182 }
183 
storage_file_delete(struct storage_msg * msg,const void * r,size_t req_len,struct watcher * watcher)184 int storage_file_delete(struct storage_msg* msg, const void* r, size_t req_len,
185                         struct watcher* watcher) {
186     char *path = NULL;
187     const struct storage_file_delete_req *req = r;
188 
189     if (req_len < sizeof(*req)) {
190         ALOGE("%s: invalid request length (%zd < %zd)\n",
191               __func__, req_len, sizeof(*req));
192         msg->result = STORAGE_ERR_NOT_VALID;
193         goto err_response;
194     }
195 
196     size_t fname_len = strlen(req->name);
197     if (fname_len != req_len - sizeof(*req)) {
198         ALOGE("%s: invalid filename length (%zd != %zd)\n",
199               __func__, fname_len, req_len - sizeof(*req));
200         msg->result = STORAGE_ERR_NOT_VALID;
201         goto err_response;
202     }
203 
204     int rc = asprintf(&path, "%s/%s", ssdir_name, req->name);
205     if (rc < 0) {
206         ALOGE("%s: asprintf failed\n", __func__);
207         msg->result = STORAGE_ERR_GENERIC;
208         goto err_response;
209     }
210 
211     watch_progress(watcher, "unlinking file");
212     rc = unlink(path);
213     if (rc < 0) {
214         rc = errno;
215         if (errno == ENOENT) {
216             ALOGV("%s: error (%d) unlinking file '%s'\n",
217                   __func__, rc, path);
218         } else {
219             ALOGE("%s: error (%d) unlinking file '%s'\n",
220                   __func__, rc, path);
221         }
222         msg->result = translate_errno(rc);
223         goto err_response;
224     }
225 
226     ALOGV("%s: \"%s\"\n", __func__, path);
227     msg->result = STORAGE_NO_ERROR;
228 
229 err_response:
230     if (path)
231         free(path);
232     return ipc_respond(msg, NULL, 0);
233 }
234 
sync_parent(const char * path,struct watcher * watcher)235 static void sync_parent(const char* path, struct watcher* watcher) {
236     int parent_fd;
237     watch_progress(watcher, "syncing parent");
238     char* parent_path = dirname(path);
239     parent_fd = TEMP_FAILURE_RETRY(open(parent_path, O_RDONLY));
240     if (parent_fd >= 0) {
241         fsync(parent_fd);
242         close(parent_fd);
243     } else {
244         ALOGE("%s: failed to open parent directory \"%s\" for sync: %s\n", __func__, parent_path,
245               strerror(errno));
246     }
247     watch_progress(watcher, "done syncing parent");
248 }
249 
storage_file_open(struct storage_msg * msg,const void * r,size_t req_len,struct watcher * watcher)250 int storage_file_open(struct storage_msg* msg, const void* r, size_t req_len,
251                       struct watcher* watcher) {
252     char* path = NULL;
253     const struct storage_file_open_req *req = r;
254     struct storage_file_open_resp resp = {0};
255 
256     if (req_len < sizeof(*req)) {
257         ALOGE("%s: invalid request length (%zd < %zd)\n",
258                __func__, req_len, sizeof(*req));
259         msg->result = STORAGE_ERR_NOT_VALID;
260         goto err_response;
261     }
262 
263     size_t fname_len = strlen(req->name);
264     if (fname_len != req_len - sizeof(*req)) {
265         ALOGE("%s: invalid filename length (%zd != %zd)\n",
266               __func__, fname_len, req_len - sizeof(*req));
267         msg->result = STORAGE_ERR_NOT_VALID;
268         goto err_response;
269     }
270 
271     /*
272      * TODO(b/210501710): Expose GSI image running state to vendor
273      * storageproxyd. We want to control data file paths in vendor_init, but we
274      * don't have access to the necessary property there yet. When we have
275      * access to that property we can set the root data path read-only and only
276      * allow creation of files in alternate/. Checking paths here temporarily
277      * until that is fixed.
278      *
279      * We are just checking for "/" instead of "alternate/" because we still
280      * want to still allow access to "persist/" in alternate mode (for now, this
281      * may change in the future).
282      */
283     if (alternate_mode && !strchr(req->name, '/')) {
284         ALOGE("%s: Cannot open root data file \"%s\" in alternate mode\n", __func__, req->name);
285         msg->result = STORAGE_ERR_ACCESS;
286         goto err_response;
287     }
288 
289     int rc = asprintf(&path, "%s/%s", ssdir_name, req->name);
290     if (rc < 0) {
291         ALOGE("%s: asprintf failed\n", __func__);
292         msg->result = STORAGE_ERR_GENERIC;
293         goto err_response;
294     }
295 
296     int open_flags = O_RDWR;
297 
298     if (req->flags & STORAGE_FILE_OPEN_TRUNCATE)
299         open_flags |= O_TRUNC;
300 
301     if (req->flags & STORAGE_FILE_OPEN_CREATE) {
302         /*
303          * Create the alternate parent dir if needed & allowed.
304          *
305          * TODO(b/210501710): Expose GSI image running state to vendor
306          * storageproxyd. This directory should be created by vendor_init, once
307          * it has access to the necessary bit of information.
308          */
309         if (strstr(req->name, ALTERNATE_DATA_DIR) == req->name) {
310             char* parent_path = dirname(path);
311             rc = mkdir(parent_path, S_IRWXU);
312             if (rc == 0) {
313                 sync_parent(parent_path, watcher);
314             } else if (errno != EEXIST) {
315                 ALOGE("%s: Could not create parent directory \"%s\": %s\n", __func__, parent_path,
316                       strerror(errno));
317             }
318         }
319 
320         /* open or create */
321         if (req->flags & STORAGE_FILE_OPEN_CREATE_EXCLUSIVE) {
322             /* create exclusive */
323             open_flags |= O_CREAT | O_EXCL;
324             rc = TEMP_FAILURE_RETRY(open(path, open_flags, S_IRUSR | S_IWUSR));
325         } else {
326             /* try open first */
327             rc = TEMP_FAILURE_RETRY(open(path, open_flags, S_IRUSR | S_IWUSR));
328             if (rc == -1 && errno == ENOENT) {
329                 /* then try open with O_CREATE */
330                 open_flags |= O_CREAT;
331                 rc = TEMP_FAILURE_RETRY(open(path, open_flags, S_IRUSR | S_IWUSR));
332             }
333 
334         }
335     } else {
336         /* open an existing file */
337         rc = TEMP_FAILURE_RETRY(open(path, open_flags, S_IRUSR | S_IWUSR));
338     }
339 
340     if (rc < 0) {
341         rc = errno;
342         if (errno == EEXIST || errno == ENOENT) {
343             ALOGV("%s: failed to open file \"%s\": %s\n",
344                   __func__, path, strerror(errno));
345         } else {
346             ALOGE("%s: failed to open file \"%s\": %s\n",
347                   __func__, path, strerror(errno));
348         }
349         msg->result = translate_errno(rc);
350         goto err_response;
351     }
352 
353     if (open_flags & O_CREAT) {
354         sync_parent(path, watcher);
355     }
356     free(path);
357 
358     /* at this point rc contains storage file fd */
359     msg->result = STORAGE_NO_ERROR;
360     resp.handle = insert_fd(open_flags, rc);
361     ALOGV("%s: \"%s\": fd = %u: handle = %d\n",
362           __func__, path, rc, resp.handle);
363 
364     /* a backing file has been opened, notify any waiting init steps */
365     if (!fs_ready_initialized) {
366         rc = property_set(FS_READY_PROPERTY, "1");
367         if (rc == 0) {
368             fs_ready_initialized = true;
369         } else {
370             ALOGE("Could not set property %s, rc: %d\n", FS_READY_PROPERTY, rc);
371         }
372     }
373 
374     return ipc_respond(msg, &resp, sizeof(resp));
375 
376 err_response:
377     if (path)
378         free(path);
379     return ipc_respond(msg, NULL, 0);
380 }
381 
storage_file_close(struct storage_msg * msg,const void * r,size_t req_len,struct watcher * watcher)382 int storage_file_close(struct storage_msg* msg, const void* r, size_t req_len,
383                        struct watcher* watcher) {
384     const struct storage_file_close_req *req = r;
385 
386     if (req_len != sizeof(*req)) {
387         ALOGE("%s: invalid request length (%zd != %zd)\n",
388               __func__, req_len, sizeof(*req));
389         msg->result = STORAGE_ERR_NOT_VALID;
390         goto err_response;
391     }
392 
393     int fd = remove_fd(req->handle);
394     ALOGV("%s: handle = %u: fd = %u\n", __func__, req->handle, fd);
395 
396     watch_progress(watcher, "fsyncing before file close");
397     int rc = fsync(fd);
398     watch_progress(watcher, "done fsyncing before file close");
399     if (rc < 0) {
400         rc = errno;
401         ALOGE("%s: fsync failed for fd=%u: %s\n",
402               __func__, fd, strerror(errno));
403         msg->result = translate_errno(rc);
404         goto err_response;
405     }
406 
407     rc = close(fd);
408     if (rc < 0) {
409         rc = errno;
410         ALOGE("%s: close failed for fd=%u: %s\n",
411               __func__, fd, strerror(errno));
412         msg->result = translate_errno(rc);
413         goto err_response;
414     }
415 
416     msg->result = STORAGE_NO_ERROR;
417 
418 err_response:
419     return ipc_respond(msg, NULL, 0);
420 }
421 
storage_file_write(struct storage_msg * msg,const void * r,size_t req_len,struct watcher * watcher)422 int storage_file_write(struct storage_msg* msg, const void* r, size_t req_len,
423                        struct watcher* watcher) {
424     int rc;
425     const struct storage_file_write_req *req = r;
426 
427     if (req_len < sizeof(*req)) {
428         ALOGE("%s: invalid request length (%zd < %zd)\n",
429               __func__, req_len, sizeof(*req));
430         msg->result = STORAGE_ERR_NOT_VALID;
431         goto err_response;
432     }
433 
434     int fd = lookup_fd(req->handle, true);
435     watch_progress(watcher, "writing");
436     if (write_with_retry(fd, &req->data[0], req_len - sizeof(*req),
437                          req->offset) < 0) {
438         watch_progress(watcher, "writing done w/ error");
439         rc = errno;
440         ALOGW("%s: error writing file (fd=%d): %s\n",
441               __func__, fd, strerror(errno));
442         msg->result = translate_errno(rc);
443         goto err_response;
444     }
445     watch_progress(watcher, "writing done");
446 
447     if (msg->flags & STORAGE_MSG_FLAG_POST_COMMIT) {
448         rc = storage_sync_checkpoint(watcher);
449         if (rc < 0) {
450             msg->result = STORAGE_ERR_SYNC_FAILURE;
451             goto err_response;
452         }
453     }
454 
455     msg->result = STORAGE_NO_ERROR;
456 
457 err_response:
458     return ipc_respond(msg, NULL, 0);
459 }
460 
storage_file_read(struct storage_msg * msg,const void * r,size_t req_len,struct watcher * watcher)461 int storage_file_read(struct storage_msg* msg, const void* r, size_t req_len,
462                       struct watcher* watcher) {
463     int rc;
464     const struct storage_file_read_req *req = r;
465 
466     if (req_len != sizeof(*req)) {
467         ALOGE("%s: invalid request length (%zd != %zd)\n",
468               __func__, req_len, sizeof(*req));
469         msg->result = STORAGE_ERR_NOT_VALID;
470         goto err_response;
471     }
472 
473     if (req->size > MAX_READ_SIZE) {
474         ALOGW("%s: request is too large (%u > %d) - refusing\n",
475               __func__, req->size, MAX_READ_SIZE);
476         msg->result = STORAGE_ERR_NOT_VALID;
477         goto err_response;
478     }
479 
480     int fd = lookup_fd(req->handle, false);
481     watch_progress(watcher, "reading");
482     ssize_t read_res = read_with_retry(fd, read_rsp.hdr.data, req->size,
483                                        (off_t)req->offset);
484     watch_progress(watcher, "reading done");
485     if (read_res < 0) {
486         rc = errno;
487         ALOGW("%s: error reading file (fd=%d): %s\n",
488               __func__, fd, strerror(errno));
489         msg->result = translate_errno(rc);
490         goto err_response;
491     }
492 
493     msg->result = STORAGE_NO_ERROR;
494     return ipc_respond(msg, &read_rsp, read_res + sizeof(read_rsp.hdr));
495 
496 err_response:
497     return ipc_respond(msg, NULL, 0);
498 }
499 
storage_file_get_size(struct storage_msg * msg,const void * r,size_t req_len,struct watcher * watcher)500 int storage_file_get_size(struct storage_msg* msg, const void* r, size_t req_len,
501                           struct watcher* watcher) {
502     const struct storage_file_get_size_req *req = r;
503     struct storage_file_get_size_resp resp = {0};
504 
505     if (req_len != sizeof(*req)) {
506         ALOGE("%s: invalid request length (%zd != %zd)\n",
507               __func__, req_len, sizeof(*req));
508         msg->result = STORAGE_ERR_NOT_VALID;
509         goto err_response;
510     }
511 
512     struct stat stat;
513     int fd = lookup_fd(req->handle, false);
514     watch_progress(watcher, "fstat");
515     int rc = fstat(fd, &stat);
516     watch_progress(watcher, "fstat done");
517     if (rc < 0) {
518         rc = errno;
519         ALOGE("%s: error stat'ing file (fd=%d): %s\n",
520               __func__, fd, strerror(errno));
521         msg->result = translate_errno(rc);
522         goto err_response;
523     }
524 
525     resp.size = stat.st_size;
526     msg->result = STORAGE_NO_ERROR;
527     return ipc_respond(msg, &resp, sizeof(resp));
528 
529 err_response:
530     return ipc_respond(msg, NULL, 0);
531 }
532 
storage_file_set_size(struct storage_msg * msg,const void * r,size_t req_len,struct watcher * watcher)533 int storage_file_set_size(struct storage_msg* msg, const void* r, size_t req_len,
534                           struct watcher* watcher) {
535     const struct storage_file_set_size_req *req = r;
536 
537     if (req_len != sizeof(*req)) {
538         ALOGE("%s: invalid request length (%zd != %zd)\n",
539               __func__, req_len, sizeof(*req));
540         msg->result = STORAGE_ERR_NOT_VALID;
541         goto err_response;
542     }
543 
544     int fd = lookup_fd(req->handle, true);
545     watch_progress(watcher, "ftruncate");
546     int rc = TEMP_FAILURE_RETRY(ftruncate(fd, req->size));
547     watch_progress(watcher, "ftruncate done");
548     if (rc < 0) {
549         rc = errno;
550         ALOGE("%s: error truncating file (fd=%d): %s\n",
551               __func__, fd, strerror(errno));
552         msg->result = translate_errno(rc);
553         goto err_response;
554     }
555 
556     msg->result = STORAGE_NO_ERROR;
557 
558 err_response:
559     return ipc_respond(msg, NULL, 0);
560 }
561 
storage_file_get_max_size(struct storage_msg * msg,const void * r,size_t req_len,struct watcher * watcher)562 int storage_file_get_max_size(struct storage_msg* msg, const void* r, size_t req_len,
563                               struct watcher* watcher) {
564     const struct storage_file_get_max_size_req* req = r;
565     struct storage_file_get_max_size_resp resp = {0};
566     uint64_t max_size = 0;
567 
568     if (req_len != sizeof(*req)) {
569         ALOGE("%s: invalid request length (%zd != %zd)\n", __func__, req_len, sizeof(*req));
570         msg->result = STORAGE_ERR_NOT_VALID;
571         goto err_response;
572     }
573 
574     struct stat stat;
575     int fd = lookup_fd(req->handle, false);
576     watch_progress(watcher, "fstat to get max size");
577     int rc = fstat(fd, &stat);
578     watch_progress(watcher, "fstat to get max size done");
579     if (rc < 0) {
580         ALOGE("%s: error stat'ing file (fd=%d): %s\n", __func__, fd, strerror(errno));
581         goto err_response;
582     }
583 
584     if ((stat.st_mode & S_IFMT) == S_IFBLK) {
585         rc = ioctl(fd, BLKGETSIZE64, &max_size);
586         if (rc < 0) {
587             rc = errno;
588             ALOGE("%s: error calling ioctl on file (fd=%d): %s\n", __func__, fd, strerror(errno));
589             msg->result = translate_errno(rc);
590             goto err_response;
591         }
592     } else {
593         max_size = MAX_FILE_SIZE;
594     }
595 
596     resp.max_size = max_size;
597     msg->result = STORAGE_NO_ERROR;
598     return ipc_respond(msg, &resp, sizeof(resp));
599 
600 err_response:
601     return ipc_respond(msg, NULL, 0);
602 }
603 
storage_init(const char * dirname)604 int storage_init(const char *dirname)
605 {
606     /* If there is an active DSU image, use the alternate fs mode. */
607     alternate_mode = is_gsi_running();
608 
609     fs_state = SS_CLEAN;
610     for (uint i = 0; i < FD_TBL_SIZE; i++) {
611         fd_state[i] = SS_UNUSED;  /* uninstalled */
612     }
613 
614     ssdir_name = dirname;
615     return 0;
616 }
617 
storage_sync_checkpoint(struct watcher * watcher)618 int storage_sync_checkpoint(struct watcher* watcher) {
619     int rc;
620 
621     watch_progress(watcher, "sync fd table");
622     /* sync fd table and reset it to clean state first */
623     for (uint fd = 0; fd < FD_TBL_SIZE; fd++) {
624          if (fd_state[fd] == SS_DIRTY) {
625              if (fs_state == SS_CLEAN) {
626                  /* need to sync individual fd */
627                  rc = fsync(fd);
628                  if (rc < 0) {
629                      ALOGE("fsync for fd=%d failed: %s\n", fd, strerror(errno));
630                      return rc;
631                  }
632              }
633              fd_state[fd] = SS_CLEAN; /* set to clean */
634          }
635     }
636 
637     /* check if we need to sync all filesystems */
638     if (fs_state == SS_DIRTY) {
639         /*
640          * We sync all filesystems here because we don't know what filesystem
641          * needs syncing if there happen to be other filesystems symlinked under
642          * the root data directory. This should not happen in the normal case
643          * because our fd table is large enough to handle the few open files we
644          * use.
645          */
646          watch_progress(watcher, "all fs sync");
647          sync();
648          fs_state = SS_CLEAN;
649     }
650 
651     watch_progress(watcher, "done syncing");
652 
653     return 0;
654 }
655