xref: /optee_os/core/tee/tee_ree_fs.c (revision a025a92a704a89d7b9892609bd7917029eb84e44)
1 /*
2  * Copyright (c) 2015, Linaro Limited
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <assert.h>
30 #include <mm/core_memprot.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <string_ext.h>
35 #include <tee/tee_fs.h>
36 #include <tee/tee_fs_defs.h>
37 #include <tee/tee_fs_key_manager.h>
38 #include <tee/tee_cryp_provider.h>
39 #include <kernel/tee_common_unpg.h>
40 #include <kernel/handle.h>
41 #include <kernel/mutex.h>
42 #include <kernel/thread.h>
43 #include <trace.h>
44 #include <optee_msg.h>
45 
46 struct tee_fs_dir {
47 	int nw_dir;
48 	struct tee_fs_dirent d;
49 };
50 
51 /* TEE FS operation */
52 #define TEE_FS_OPEN       1
53 #define TEE_FS_CLOSE      2
54 #define TEE_FS_READ       3
55 #define TEE_FS_WRITE      4
56 #define TEE_FS_SEEK       5
57 #define TEE_FS_UNLINK     6
58 #define TEE_FS_RENAME     7
59 #define TEE_FS_TRUNC      8
60 #define TEE_FS_MKDIR      9
61 #define TEE_FS_OPENDIR   10
62 #define TEE_FS_CLOSEDIR  11
63 #define TEE_FS_READDIR   12
64 #define TEE_FS_RMDIR     13
65 #define TEE_FS_ACCESS    14
66 #define TEE_FS_LINK      15
67 
68 #define BLOCK_FILE_SHIFT	12
69 
70 #define BLOCK_FILE_SIZE		(1 << BLOCK_FILE_SHIFT)
71 
72 #define MAX_NUM_CACHED_BLOCKS	1
73 
74 #define NUM_BLOCKS_PER_FILE	1024
75 
76 #define MAX_FILE_SIZE	(BLOCK_FILE_SIZE * NUM_BLOCKS_PER_FILE)
77 
78 struct tee_fs_file_info {
79 	size_t length;
80 	uint32_t backup_version_table[NUM_BLOCKS_PER_FILE / 32];
81 };
82 
83 struct tee_fs_file_meta {
84 	struct tee_fs_file_info info;
85 	uint8_t encrypted_fek[TEE_FS_KM_FEK_SIZE];
86 	uint8_t backup_version;
87 };
88 
89 TAILQ_HEAD(block_head, block);
90 
91 struct block {
92 	TAILQ_ENTRY(block) list;
93 	int block_num;
94 	uint8_t *data;
95 	size_t data_size;
96 };
97 
98 struct block_cache {
99 	struct block_head block_lru;
100 	uint8_t cached_block_num;
101 };
102 
103 struct tee_fs_fd {
104 	struct tee_fs_file_meta *meta;
105 	int pos;
106 	uint32_t flags;
107 	int fd;
108 	bool is_new_file;
109 	char *filename;
110 	struct block_cache block_cache;
111 };
112 
113 int tee_fs_common_open(TEE_Result *errno, const char *file, int flags, ...);
114 int tee_fs_common_close(struct tee_fs_fd *fdp);
115 tee_fs_off_t tee_fs_common_lseek(TEE_Result *errno, struct tee_fs_fd *fdp,
116 				 tee_fs_off_t offset, int whence);
117 int tee_fs_common_ftruncate(TEE_Result *errno, struct tee_fs_fd *fdp,
118 			    tee_fs_off_t length);
119 int tee_fs_common_read(TEE_Result *errno, struct tee_fs_fd *fdp,
120 		       void *buf, size_t len);
121 int tee_fs_common_write(TEE_Result *errno, struct tee_fs_fd *fdp,
122 			const void *buf, size_t len);
123 int tee_fs_common_rename(const char *old, const char *new);
124 int tee_fs_common_unlink(const char *file);
125 int tee_fs_common_mkdir(const char *path, tee_fs_mode_t mode);
126 tee_fs_dir *tee_fs_common_opendir(const char *name);
127 int tee_fs_common_closedir(tee_fs_dir *d);
128 struct tee_fs_dirent *tee_fs_common_readdir(tee_fs_dir *d);
129 int tee_fs_common_rmdir(const char *name);
130 int tee_fs_common_access(const char *name, int mode);
131 
132 static inline int pos_to_block_num(int position)
133 {
134 	return position >> BLOCK_FILE_SHIFT;
135 }
136 
137 static inline int get_last_block_num(size_t size)
138 {
139 	return pos_to_block_num(size - 1);
140 }
141 
142 static inline uint8_t get_backup_version_of_block(
143 		struct tee_fs_file_meta *meta,
144 		size_t block_num)
145 {
146 	uint32_t index = (block_num / 32);
147 	uint32_t block_mask = 1 << (block_num % 32);
148 
149 	return !!(meta->info.backup_version_table[index] & block_mask);
150 }
151 
152 static inline void toggle_backup_version_of_block(
153 		struct tee_fs_file_meta *meta,
154 		size_t block_num)
155 {
156 	uint32_t index = (block_num / 32);
157 	uint32_t block_mask = 1 << (block_num % 32);
158 
159 	meta->info.backup_version_table[index] ^= block_mask;
160 }
161 
162 struct block_operations {
163 
164 	/*
165 	 * Read a block from REE File System which is corresponding
166 	 * to the given block_num.
167 	 */
168 	struct block *(*read)(struct tee_fs_fd *fdp, int block_num);
169 
170 	/*
171 	 * Write the given block to REE File System
172 	 */
173 	int (*write)(struct tee_fs_fd *fdp, struct block *b,
174 			struct tee_fs_file_meta *new_meta);
175 };
176 
177 static int tee_fs_send_cmd(struct tee_fs_rpc *bf_cmd, void *data, uint32_t len,
178 			   uint32_t mode)
179 {
180 	TEE_Result ret;
181 	struct optee_msg_param params;
182 	paddr_t phpayload = 0;
183 	uint64_t cpayload = 0;
184 	struct tee_fs_rpc *bf;
185 	int res = -1;
186 
187 	thread_rpc_alloc_payload(sizeof(struct tee_fs_rpc) + len,
188 				 &phpayload, &cpayload);
189 	if (!phpayload)
190 		return -1;
191 
192 	if (!ALIGNMENT_IS_OK(phpayload, struct tee_fs_rpc))
193 		goto exit;
194 
195 	bf = phys_to_virt(phpayload, MEM_AREA_NSEC_SHM);
196 	if (!bf)
197 		goto exit;
198 
199 	memset(&params, 0, sizeof(params));
200 	params.attr = OPTEE_MSG_ATTR_TYPE_TMEM_INOUT;
201 	params.u.tmem.buf_ptr = phpayload;
202 	params.u.tmem.size = sizeof(struct tee_fs_rpc) + len;
203 	params.u.tmem.shm_ref = cpayload;
204 
205 	/* fill in parameters */
206 	*bf = *bf_cmd;
207 
208 	if (mode & TEE_FS_MODE_IN) {
209 		memcpy((void *)(bf + 1), data, len);
210 	}
211 
212 	ret = thread_rpc_cmd(OPTEE_MSG_RPC_CMD_FS, 1, &params);
213 	/* update result */
214 	*bf_cmd = *bf;
215 	if (ret != TEE_SUCCESS)
216 		goto exit;
217 
218 	if (mode & TEE_FS_MODE_OUT) {
219 		uint32_t olen = MIN(len, bf->len);
220 
221 		memcpy(data, (void *)(bf + 1), olen);
222 	}
223 
224 	res = 0;
225 
226 exit:
227 	thread_rpc_free_payload(cpayload);
228 	return res;
229 }
230 
231 /*
232  * We split a TEE file into multiple blocks and store them
233  * on REE filesystem. A TEE file is represented by a REE file
234  * called meta and a number of REE files called blocks. Meta
235  * file is used for storing file information, e.g. file size
236  * and backup version of each block.
237  *
238  * REE files naming rule is as follows:
239  *
240  *   <tee_file_name>/meta.<backup_version>
241  *   <tee_file_name>/block0.<backup_version>
242  *   ...
243  *   <tee_file_name>/block15.<backup_version>
244  *
245  * Backup_version is used to support atomic update operation.
246  * Original file will not be updated, instead we create a new
247  * version of the same file and update the new file instead.
248  *
249  * The backup_version of each block file is stored in meta
250  * file, the meta file itself also has backup_version, the update is
251  * successful after new version of meta has been written.
252  */
253 #define REE_FS_NAME_MAX (TEE_FS_NAME_MAX + 20)
254 
255 static struct handle_db fs_handle_db = HANDLE_DB_INITIALIZER;
256 
257 static int ree_fs_open(const char *file, int flags, ...)
258 {
259 	int res = -1;
260 	struct tee_fs_rpc head = { 0 };
261 	size_t len;
262 
263 	len = strlen(file) + 1;
264 	if (len > REE_FS_NAME_MAX)
265 		goto exit;
266 
267 	/* fill in parameters */
268 	head.op = TEE_FS_OPEN;
269 	head.flags = flags;
270 	head.fd = 0;
271 
272 	res = tee_fs_send_cmd(&head, (void *)file, len, TEE_FS_MODE_IN);
273 	if (!res)
274 		res = head.res;
275 
276 exit:
277 	return res;
278 }
279 
280 static int ree_fs_read(int fd, void *buf, size_t len)
281 {
282 	int res = -1;
283 	struct tee_fs_rpc head = { 0 };
284 
285 	if (!len) {
286 		res = 0;
287 		goto exit;
288 	}
289 
290 	if (!buf)
291 		goto exit;
292 
293 	/* fill in parameters */
294 	head.op = TEE_FS_READ;
295 	head.fd = fd;
296 	head.len = (uint32_t) len;
297 
298 	res = tee_fs_send_cmd(&head, (void *)buf, len, TEE_FS_MODE_OUT);
299 	if (!res)
300 		res = head.res;
301 exit:
302 	return res;
303 }
304 
305 static int ree_fs_write(int fd,
306 			const void *buf, size_t len)
307 {
308 	int res = -1;
309 	struct tee_fs_rpc head = { 0 };
310 
311 	if (!len) {
312 		res = 0;
313 		goto exit;
314 	}
315 
316 	if (!buf)
317 		goto exit;
318 
319 	/* fill in parameters */
320 	head.op = TEE_FS_WRITE;
321 	head.fd = fd;
322 	head.len = (uint32_t) len;
323 
324 	res = tee_fs_send_cmd(&head, (void *)buf, len, TEE_FS_MODE_IN);
325 	if (!res)
326 		res = head.res;
327 exit:
328 	return res;
329 }
330 
331 static int ree_fs_ftruncate(int fd, tee_fs_off_t length)
332 {
333 	int res = -1;
334 	struct tee_fs_rpc head = { 0 };
335 
336 	head.op = TEE_FS_TRUNC;
337 	head.fd = fd;
338 	head.arg = length;
339 
340 	res = tee_fs_send_cmd(&head, NULL, 0, TEE_FS_MODE_NONE);
341 	if (!res)
342 		res = head.res;
343 
344 	return res;
345 }
346 
347 static int ree_fs_close(int fd)
348 {
349 	int res = -1;
350 	struct tee_fs_rpc head = { 0 };
351 
352 	/* fill in parameters */
353 	head.op = TEE_FS_CLOSE;
354 	head.fd = fd;
355 
356 	res = tee_fs_send_cmd(&head, NULL, 0, TEE_FS_MODE_NONE);
357 	if (!res)
358 		res = head.res;
359 
360 	return res;
361 }
362 
363 static tee_fs_off_t ree_fs_lseek(int fd, tee_fs_off_t offset, int whence)
364 {
365 	tee_fs_off_t res = -1;
366 	struct tee_fs_rpc head = { 0 };
367 
368 	/* fill in parameters */
369 	head.op = TEE_FS_SEEK;
370 	head.fd = fd;
371 	head.arg = offset;
372 	head.flags = whence;
373 
374 	res = tee_fs_send_cmd(&head, NULL, 0, TEE_FS_MODE_NONE);
375 	if (!res)
376 		res = head.res;
377 
378 	return res;
379 }
380 
381 static int ree_fs_mkdir(const char *path, tee_fs_mode_t mode)
382 {
383 	int res = -1;
384 	struct tee_fs_rpc head = { 0 };
385 	uint32_t len;
386 
387 	if (!path)
388 		return -1;
389 
390 	len = strlen(path) + 1;
391 	if (len > REE_FS_NAME_MAX)
392 		goto exit;
393 
394 	head.op = TEE_FS_MKDIR;
395 	head.flags = mode;
396 
397 	res = tee_fs_send_cmd(&head, (void *)path, len, TEE_FS_MODE_IN);
398 	if (!res)
399 		res = head.res;
400 
401 exit:
402 	return res;
403 }
404 
405 static tee_fs_dir *ree_fs_opendir(const char *name)
406 {
407 	struct tee_fs_rpc head = { 0 };
408 	uint32_t len;
409 	struct tee_fs_dir *dir = NULL;
410 
411 	if (!name)
412 		goto exit;
413 
414 	len = strlen(name) + 1;
415 	if (len > TEE_FS_NAME_MAX)
416 		goto exit;
417 
418 	head.op = TEE_FS_OPENDIR;
419 
420 	if (tee_fs_send_cmd(&head, (void *)name, len, TEE_FS_MODE_IN))
421 		goto exit;
422 
423 	if (head.res < 0)
424 		goto exit;
425 
426 	dir = malloc(sizeof(struct tee_fs_dir));
427 	if (!dir) {
428 		int nw_dir = head.res;
429 
430 		memset(&head, 0, sizeof(head));
431 		head.op = TEE_FS_CLOSEDIR;
432 		head.arg = nw_dir;
433 		tee_fs_send_cmd(&head, NULL, 0, TEE_FS_MODE_NONE);
434 		goto exit;
435 	}
436 
437 	dir->nw_dir = head.res;
438 	dir->d.d_name = NULL;
439 
440 exit:
441 	return dir;
442 }
443 
444 static int ree_fs_closedir(tee_fs_dir *d)
445 {
446 	int res = -1;
447 	struct tee_fs_rpc head = { 0 };
448 
449 	if (!d) {
450 		res = 0;
451 		goto exit;
452 	}
453 
454 	head.op = TEE_FS_CLOSEDIR;
455 	head.arg = (int)d->nw_dir;
456 
457 	res = tee_fs_send_cmd(&head, NULL, 0, TEE_FS_MODE_NONE);
458 	if (!res)
459 		res = head.res;
460 
461 exit:
462 	if (d)
463 		free(d->d.d_name);
464 	free(d);
465 
466 	return res;
467 }
468 
469 static struct tee_fs_dirent *ree_fs_readdir(tee_fs_dir *d)
470 {
471 	struct tee_fs_dirent *res = NULL;
472 	struct tee_fs_rpc head = { 0 };
473 	char fname[TEE_FS_NAME_MAX + 1];
474 
475 	if (!d)
476 		goto exit;
477 
478 	head.op = TEE_FS_READDIR;
479 	head.arg = (int)d->nw_dir;
480 
481 	if (tee_fs_send_cmd(&head, fname, sizeof(fname), TEE_FS_MODE_OUT))
482 		goto exit;
483 
484 	if (head.res < 0)
485 		goto exit;
486 
487 	if (!head.len || head.len > sizeof(fname))
488 		goto exit;
489 
490 	fname[head.len - 1] = '\0'; /* make sure it's zero terminated */
491 	free(d->d.d_name);
492 	d->d.d_name = strdup(fname);
493 	if (!d->d.d_name)
494 		goto exit;
495 
496 	res = &d->d;
497 exit:
498 	return res;
499 }
500 
501 static int ree_fs_rmdir(const char *name)
502 {
503 	int res = -1;
504 	struct tee_fs_rpc head = { 0 };
505 	uint32_t len;
506 
507 	len = strlen(name) + 1;
508 	if (len > REE_FS_NAME_MAX)
509 		goto exit;
510 
511 	head.op = TEE_FS_RMDIR;
512 
513 	res = tee_fs_send_cmd(&head, (void *)name, len, TEE_FS_MODE_IN);
514 	if (!res)
515 		res = head.res;
516 
517 exit:
518 	return res;
519 }
520 
521 static int ree_fs_link(const char *old, const char *new)
522 {
523 	int res = -1;
524 	char *tmp = NULL;
525 	struct tee_fs_rpc head = { 0 };
526 	size_t len_old = strlen(old) + 1;
527 	size_t len_new = strlen(new) + 1;
528 	size_t len = len_old + len_new;
529 
530 	if (len_old > REE_FS_NAME_MAX || len_new > REE_FS_NAME_MAX)
531 		goto exit;
532 
533 	tmp = malloc(len);
534 	if (!tmp)
535 		goto exit;
536 	memcpy(tmp, old, len_old);
537 	memcpy(tmp + len_old, new, len_new);
538 
539 	head.op = TEE_FS_LINK;
540 
541 	res = tee_fs_send_cmd(&head, tmp, len, TEE_FS_MODE_IN);
542 	if (!res)
543 		res = head.res;
544 
545 exit:
546 	free(tmp);
547 	return res;
548 }
549 
550 static int ree_fs_unlink(const char *file)
551 {
552 	int res = -1;
553 	struct tee_fs_rpc head = { 0 };
554 	size_t len = strlen(file) + 1;
555 
556 	if (len > REE_FS_NAME_MAX)
557 		goto exit;
558 
559 	head.op = TEE_FS_UNLINK;
560 
561 	res = tee_fs_send_cmd(&head, (void *)file, len, TEE_FS_MODE_IN);
562 	if (!res)
563 		res = head.res;
564 exit:
565 	return res;
566 }
567 
568 static int ree_fs_access(const char *name, int mode)
569 {
570 	int res = -1;
571 	struct tee_fs_rpc head = { 0 };
572 	uint32_t len;
573 
574 	if (!name)
575 		goto exit;
576 
577 	len = strlen(name) + 1;
578 	if (len > TEE_FS_NAME_MAX)
579 		goto exit;
580 
581 	head.op = TEE_FS_ACCESS;
582 	head.flags = mode;
583 
584 	res = tee_fs_send_cmd(&head, (void *)name, len, TEE_FS_MODE_IN);
585 	if (!res)
586 		res = head.res;
587 
588 exit:
589 	return res;
590 }
591 
592 static int get_file_length(int fd, size_t *length)
593 {
594 	size_t file_len;
595 	int res;
596 
597 	TEE_ASSERT(length);
598 
599 	*length = 0;
600 
601 	res = ree_fs_lseek(fd, 0, TEE_FS_SEEK_END);
602 	if (res < 0)
603 		return res;
604 
605 	file_len = res;
606 
607 	res = ree_fs_lseek(fd, 0, TEE_FS_SEEK_SET);
608 	if (res < 0)
609 		return res;
610 
611 	*length = file_len;
612 	return 0;
613 }
614 
615 static void get_meta_filepath(const char *file, int version,
616 				char *meta_path)
617 {
618 	snprintf(meta_path, REE_FS_NAME_MAX, "%s/meta.%d",
619 			file, version);
620 }
621 
622 static void get_block_filepath(const char *file, size_t block_num,
623 				int version, char *meta_path)
624 {
625 	snprintf(meta_path, REE_FS_NAME_MAX, "%s/block%zu.%d",
626 			file, block_num, version);
627 }
628 
629 static int create_block_file(struct tee_fs_fd *fdp,
630 		struct tee_fs_file_meta *new_meta, int block_num)
631 {
632 	int fd;
633 	int res = -1;
634 	char block_path[REE_FS_NAME_MAX];
635 	uint8_t new_version =
636 		!get_backup_version_of_block(fdp->meta, block_num);
637 
638 	get_block_filepath(fdp->filename, block_num, new_version,
639 			block_path);
640 
641 	fd = ree_fs_open(block_path, TEE_FS_O_CREATE | TEE_FS_O_RDWR);
642 	if (fd < 0)
643 		goto exit;
644 
645 	res = ree_fs_ftruncate(fd, 0);
646 	if (res < 0)
647 		goto exit;
648 
649 	/*
650 	 * toggle block version in new meta to indicate
651 	 * we are currently working on new block file
652 	 */
653 	toggle_backup_version_of_block(new_meta, block_num);
654 	res = fd;
655 
656 exit:
657 	return res;
658 }
659 
660 static int __remove_block_file(struct tee_fs_fd *fdp, size_t block_num,
661 				bool toggle)
662 {
663 	char block_path[REE_FS_NAME_MAX];
664 	uint8_t version =
665 		get_backup_version_of_block(fdp->meta, block_num);
666 
667 	if (toggle)
668 		version = !version;
669 
670 	get_block_filepath(fdp->filename, block_num, version, block_path);
671 	DMSG("%s", block_path);
672 
673 	/* ignore it if file not found */
674 	if (tee_fs_common_access(block_path, TEE_FS_F_OK))
675 		return 0;
676 
677 	return ree_fs_unlink(block_path);
678 }
679 
680 static int remove_block_file(struct tee_fs_fd *fdp, size_t block_num)
681 {
682 	DMSG("remove block%zd", block_num);
683 	return __remove_block_file(fdp, block_num, false);
684 }
685 
686 static int remove_outdated_block(struct tee_fs_fd *fdp, size_t block_num)
687 {
688 	DMSG("remove outdated block%zd", block_num);
689 	return __remove_block_file(fdp, block_num, true);
690 }
691 
692 /*
693  * encrypted_fek: as input for META_FILE and BLOCK_FILE
694  */
695 static int encrypt_and_write_file(int fd,
696 		enum tee_fs_file_type file_type,
697 		void *data_in, size_t data_in_size,
698 		uint8_t *encrypted_fek)
699 {
700 	TEE_Result tee_res;
701 	int res = 0;
702 	int bytes;
703 	uint8_t *ciphertext;
704 	size_t header_size = tee_fs_get_header_size(file_type);
705 	size_t ciphertext_size = header_size + data_in_size;
706 
707 	ciphertext = malloc(ciphertext_size);
708 	if (!ciphertext) {
709 		EMSG("Failed to allocate ciphertext buffer, size=%zd",
710 				ciphertext_size);
711 		return -1;
712 	}
713 
714 	tee_res = tee_fs_encrypt_file(file_type,
715 			data_in, data_in_size,
716 			ciphertext, &ciphertext_size, encrypted_fek);
717 	if (tee_res != TEE_SUCCESS) {
718 		EMSG("error code=%x", tee_res);
719 		res = -1;
720 		goto fail;
721 	}
722 
723 	bytes = ree_fs_write(fd, ciphertext, ciphertext_size);
724 	if (bytes != (int)ciphertext_size) {
725 		EMSG("bytes(%d) != ciphertext size(%zu)",
726 				bytes, ciphertext_size);
727 		res = -1;
728 		goto fail;
729 	}
730 
731 fail:
732 	free(ciphertext);
733 
734 	return res;
735 }
736 
737 /*
738  * encrypted_fek: as output for META_FILE
739  *                as input for BLOCK_FILE
740  */
741 static int read_and_decrypt_file(int fd,
742 		enum tee_fs_file_type file_type,
743 		void *data_out, size_t *data_out_size,
744 		uint8_t *encrypted_fek)
745 {
746 	TEE_Result tee_res;
747 	int res;
748 	int bytes;
749 	void *ciphertext = NULL;
750 	size_t file_size;
751 	size_t header_size = tee_fs_get_header_size(file_type);
752 
753 	res = get_file_length(fd, &file_size);
754 	if (res < 0)
755 		return res;
756 
757 	TEE_ASSERT(file_size >= header_size);
758 
759 	ciphertext = malloc(file_size);
760 	if (!ciphertext) {
761 		EMSG("Failed to allocate file data buffer, size=%zd",
762 				file_size);
763 		return -1;
764 	}
765 
766 	bytes = ree_fs_read(fd, ciphertext, file_size);
767 	if (bytes != (int)file_size) {
768 		EMSG("return bytes(%d) != file_size(%zd)",
769 				bytes, file_size);
770 		res = -1;
771 		goto fail;
772 	}
773 
774 	tee_res = tee_fs_decrypt_file(file_type,
775 			ciphertext, file_size,
776 			data_out, data_out_size,
777 			encrypted_fek);
778 	if (tee_res != TEE_SUCCESS) {
779 		EMSG("Failed to decrypt file, res=0x%x", tee_res);
780 		res = -1;
781 	}
782 
783 fail:
784 	free(ciphertext);
785 
786 	return (res < 0) ? res : 0;
787 }
788 
789 static struct tee_fs_file_meta *duplicate_meta(
790 		struct tee_fs_fd *fdp)
791 {
792 	struct tee_fs_file_meta *new_meta = NULL;
793 
794 	new_meta = malloc(sizeof(*new_meta));
795 	if (!new_meta) {
796 		EMSG("Failed to allocate memory for new meta");
797 		goto exit;
798 	}
799 
800 	memcpy(new_meta, fdp->meta, sizeof(*new_meta));
801 
802 exit:
803 	return new_meta;
804 }
805 
806 static int write_meta_file(const char *filename,
807 		struct tee_fs_file_meta *meta)
808 {
809 	int res, fd = -1;
810 	char meta_path[REE_FS_NAME_MAX];
811 
812 	get_meta_filepath(filename, meta->backup_version, meta_path);
813 
814 	fd = ree_fs_open(meta_path, TEE_FS_O_CREATE |
815 			TEE_FS_O_TRUNC | TEE_FS_O_WRONLY);
816 	if (fd < 0)
817 		return -1;
818 
819 	res = encrypt_and_write_file(fd, META_FILE,
820 			(void *)&meta->info, sizeof(meta->info),
821 			meta->encrypted_fek);
822 
823 	ree_fs_close(fd);
824 	return res;
825 }
826 
827 static struct tee_fs_file_meta *create_meta_file(const char *file)
828 {
829 	TEE_Result tee_res;
830 	struct tee_fs_file_meta *meta = NULL;
831 	int res;
832 	const uint8_t default_backup_version = 0;
833 
834 	meta = malloc(sizeof(struct tee_fs_file_meta));
835 	if (!meta) {
836 		EMSG("Failed to allocate memory");
837 		goto exit;
838 	}
839 
840 	memset(&meta->info.backup_version_table, 0xff,
841 		sizeof(meta->info.backup_version_table));
842 	meta->info.length = 0;
843 
844 	tee_res = tee_fs_generate_fek(meta->encrypted_fek, TEE_FS_KM_FEK_SIZE);
845 	if (tee_res != TEE_SUCCESS)
846 		goto exit;
847 
848 	meta->backup_version = default_backup_version;
849 
850 	res = write_meta_file(file, meta);
851 	if (res < 0)
852 		goto exit;
853 
854 	return meta;
855 
856 exit:
857 	free(meta);
858 
859 	return NULL;
860 }
861 
862 static int commit_meta_file(struct tee_fs_fd *fdp,
863 		struct tee_fs_file_meta *new_meta)
864 {
865 	int res;
866 	uint8_t old_version;
867 	char meta_path[REE_FS_NAME_MAX];
868 
869 	old_version = new_meta->backup_version;
870 	new_meta->backup_version = !new_meta->backup_version;
871 
872 	res = write_meta_file(fdp->filename, new_meta);
873 
874 	if (res < 0)
875 		return res;
876 
877 	/*
878 	 * From now on the new meta is successfully committed,
879 	 * change tee_fs_fd accordingly
880 	 */
881 	memcpy(fdp->meta, new_meta, sizeof(*new_meta));
882 
883 	/*
884 	 * Remove outdated meta file, there is nothing we can
885 	 * do if we fail here, but that is OK because both
886 	 * new & old version of block files are kept. The context
887 	 * of the file is still consistent.
888 	 */
889 	get_meta_filepath(fdp->filename, old_version, meta_path);
890 	ree_fs_unlink(meta_path);
891 
892 	return res;
893 }
894 
895 static int read_meta_file(const char *meta_path,
896 		struct tee_fs_file_meta *meta)
897 {
898 	int res, fd;
899 	size_t meta_info_size = sizeof(struct tee_fs_file_info);
900 
901 	res = ree_fs_open(meta_path, TEE_FS_O_RDWR);
902 	if (res < 0)
903 		return res;
904 
905 	fd = res;
906 
907 	res = read_and_decrypt_file(fd, META_FILE,
908 			(void *)&meta->info, &meta_info_size,
909 			meta->encrypted_fek);
910 
911 	ree_fs_close(fd);
912 
913 	return res;
914 }
915 
916 static struct tee_fs_file_meta *open_meta_file(
917 		const char *file, int version)
918 {
919 	int res;
920 	char meta_path[REE_FS_NAME_MAX];
921 	struct tee_fs_file_meta *meta = NULL;
922 
923 	meta = malloc(sizeof(struct tee_fs_file_meta));
924 	if (!meta)
925 		return NULL;
926 
927 	get_meta_filepath(file, version, meta_path);
928 	res = read_meta_file(meta_path, meta);
929 	if (res < 0)
930 		goto exit_free_meta;
931 
932 	meta->backup_version = version;
933 
934 	return meta;
935 
936 exit_free_meta:
937 	free(meta);
938 	return NULL;
939 }
940 
941 static bool is_block_file_exist(struct tee_fs_file_meta *meta,
942 					size_t block_num)
943 {
944 	size_t file_size = meta->info.length;
945 
946 	if (file_size == 0)
947 		return false;
948 
949 	return (block_num <= (size_t)get_last_block_num(file_size));
950 }
951 
952 #ifdef CFG_ENC_FS
953 static int read_block_from_storage(struct tee_fs_fd *fdp, struct block *b)
954 {
955 	int fd, res = 0;
956 	uint8_t *plaintext = b->data;
957 	char block_path[REE_FS_NAME_MAX];
958 	size_t block_file_size = BLOCK_FILE_SIZE;
959 	uint8_t version = get_backup_version_of_block(fdp->meta,
960 			b->block_num);
961 
962 	if (!is_block_file_exist(fdp->meta, b->block_num))
963 		goto exit;
964 
965 	get_block_filepath(fdp->filename, b->block_num, version,
966 			block_path);
967 
968 	fd = ree_fs_open(block_path, TEE_FS_O_RDONLY);
969 	if (fd < 0)
970 		return fd;
971 
972 	res = read_and_decrypt_file(fd, BLOCK_FILE,
973 			plaintext, &block_file_size,
974 			fdp->meta->encrypted_fek);
975 	if (res < 0) {
976 		EMSG("Failed to read and decrypt file");
977 		goto fail;
978 	}
979 	b->data_size = block_file_size;
980 	DMSG("Successfully read and decrypt block%d from storage, size=%zd",
981 		b->block_num, b->data_size);
982 fail:
983 	ree_fs_close(fd);
984 exit:
985 	return res;
986 }
987 
988 static int flush_block_to_storage(struct tee_fs_fd *fdp, struct block *b,
989 		struct tee_fs_file_meta *new_meta)
990 {
991 	int fd = -1;
992 	int res;
993 	size_t block_num = b->block_num;
994 
995 	fd = create_block_file(
996 			fdp, new_meta, block_num);
997 	if (fd < 0) {
998 		EMSG("Failed to create new version of block");
999 		res = -1;
1000 		goto fail;
1001 	}
1002 
1003 	res = encrypt_and_write_file(fd, BLOCK_FILE,
1004 			b->data, b->data_size,
1005 			new_meta->encrypted_fek);
1006 	if (res < 0) {
1007 		EMSG("Failed to encrypt and write block file");
1008 		goto fail;
1009 	}
1010 	DMSG("Successfully encrypt and write block%d to storage, size=%zd",
1011 		b->block_num, b->data_size);
1012 
1013 fail:
1014 	if (fd > 0)
1015 		ree_fs_close(fd);
1016 
1017 	return res;
1018 }
1019 #else
1020 static int read_block_from_storage(struct tee_fs_fd *fdp, struct block *b)
1021 {
1022 	int fd, res = 0;
1023 	char block_path[REE_FS_NAME_MAX];
1024 	size_t block_file_size = BLOCK_FILE_SIZE;
1025 	uint8_t version = get_backup_version_of_block(fdp->meta,
1026 			b->block_num);
1027 
1028 	if (!is_block_file_exist(fdp->meta, b->block_num))
1029 		goto exit;
1030 
1031 	get_block_filepath(fdp->filename, b->block_num, version,
1032 			block_path);
1033 
1034 	fd = ree_fs_open(block_path, TEE_FS_O_RDONLY);
1035 	if (fd < 0)
1036 		return fd;
1037 
1038 
1039 	res = ree_fs_read(fd, b->data, block_file_size);
1040 	if (res < 0) {
1041 		EMSG("Failed to read block%d (%d)",
1042 			b->block_num, res);
1043 		goto fail;
1044 	}
1045 
1046 	b->data_size = res;
1047 	DMSG("Successfully read block%d from storage, size=%d",
1048 		b->block_num, b->data_size);
1049 	res = 0;
1050 fail:
1051 	ree_fs_close(fd);
1052 exit:
1053 	return res;
1054 }
1055 
1056 static int flush_block_to_storage(struct tee_fs_fd *fdp, struct block *b,
1057 		struct tee_fs_file_meta *new_meta)
1058 {
1059 	int fd = -1;
1060 	int res;
1061 	size_t block_num = b->block_num;
1062 
1063 	fd = create_block_file(
1064 			fdp, new_meta, block_num);
1065 	if (fd < 0) {
1066 		EMSG("Failed to create new version of block");
1067 		res = -1;
1068 		goto fail;
1069 	}
1070 
1071 	res = ree_fs_write(fd, b->data, b->data_size);
1072 	if (res < 0) {
1073 		EMSG("Failed to write block%d (%d)",
1074 			b->block_num, res);
1075 		goto fail;
1076 	}
1077 	DMSG("Successfully writen block%d to storage, size=%d",
1078 		b->block_num, b->data_size);
1079 	res = 0;
1080 fail:
1081 	if (fd > 0)
1082 		ree_fs_close(fd);
1083 
1084 	return res;
1085 }
1086 #endif
1087 
1088 static struct block *alloc_block(void)
1089 {
1090 	struct block *c;
1091 
1092 	c = malloc(sizeof(struct block));
1093 	if (!c)
1094 		return NULL;
1095 
1096 	c->data = malloc(BLOCK_FILE_SIZE);
1097 	if (!c->data) {
1098 		EMSG("unable to alloc memory for block data");
1099 		goto exit;
1100 	}
1101 
1102 	c->block_num = -1;
1103 	c->data_size = 0;
1104 
1105 	return c;
1106 
1107 exit:
1108 	free(c);
1109 	return NULL;
1110 }
1111 
1112 #ifdef CFG_FS_BLOCK_CACHE
1113 static void free_block(struct block *b)
1114 {
1115 	if (b) {
1116 		free(b->data);
1117 		free(b);
1118 	}
1119 }
1120 
1121 static inline bool is_block_data_invalid(struct block *b)
1122 {
1123 	return (b->data_size == 0);
1124 }
1125 
1126 static void get_block_from_cache(struct block_cache *cache,
1127 			int block_num, struct block **out_block)
1128 {
1129 	struct block *b, *found = NULL;
1130 
1131 	DMSG("Try to find block%d in cache", block_num);
1132 	TAILQ_FOREACH(b, &cache->block_lru, list) {
1133 		if (b->block_num == block_num) {
1134 			DMSG("Found in cache");
1135 			found = b;
1136 			break;
1137 		}
1138 	}
1139 
1140 	if (found) {
1141 		TAILQ_REMOVE(&cache->block_lru, found, list);
1142 		TAILQ_INSERT_HEAD(&cache->block_lru, found, list);
1143 		*out_block = found;
1144 		return;
1145 	}
1146 
1147 	DMSG("Not found, reuse oldest block on LRU list");
1148 	b = TAILQ_LAST(&cache->block_lru, block_head);
1149 	TAILQ_REMOVE(&cache->block_lru, b, list);
1150 	TAILQ_INSERT_HEAD(&cache->block_lru, b, list);
1151 	b->block_num = block_num;
1152 	b->data_size = 0;
1153 	*out_block = b;
1154 }
1155 
1156 static int init_block_cache(struct block_cache *cache)
1157 {
1158 	struct block *b;
1159 
1160 	TAILQ_INIT(&cache->block_lru);
1161 	cache->cached_block_num = 0;
1162 
1163 	while (cache->cached_block_num < MAX_NUM_CACHED_BLOCKS) {
1164 
1165 		b = alloc_block();
1166 		if (!b) {
1167 			EMSG("Failed to alloc block");
1168 			goto fail;
1169 		} else {
1170 			TAILQ_INSERT_HEAD(&cache->block_lru, b, list);
1171 			cache->cached_block_num++;
1172 		}
1173 	}
1174 	return 0;
1175 
1176 fail:
1177 	TAILQ_FOREACH(b, &cache->block_lru, list)
1178 		free_block(b);
1179 	return -1;
1180 }
1181 
1182 static void destroy_block_cache(struct block_cache *cache)
1183 {
1184 	struct block *b, *next;
1185 
1186 	TAILQ_FOREACH_SAFE(b, &cache->block_lru, list, next) {
1187 		TAILQ_REMOVE(&cache->block_lru, b, list);
1188 		free_block(b);
1189 	}
1190 }
1191 #else
1192 static int init_block_cache(struct block_cache *cache __unused)
1193 {
1194 	return 0;
1195 }
1196 
1197 static void destroy_block_cache(struct block_cache *cache __unused)
1198 {
1199 }
1200 #endif
1201 
1202 static void write_data_to_block(struct block *b, int offset,
1203 				void *buf, size_t len)
1204 {
1205 	DMSG("Write %zd bytes to block%d", len, b->block_num);
1206 	memcpy(b->data + offset, buf, len);
1207 	if (offset + len > b->data_size) {
1208 		b->data_size = offset + len;
1209 		DMSG("Extend block%d size to %zd bytes",
1210 				b->block_num, b->data_size);
1211 	}
1212 }
1213 
1214 static void read_data_from_block(struct block *b, int offset,
1215 				void *buf, size_t len)
1216 {
1217 	size_t bytes_to_read = len;
1218 
1219 	DMSG("Read %zd bytes from block%d", len, b->block_num);
1220 	if (offset + len > b->data_size) {
1221 		bytes_to_read = b->data_size - offset;
1222 		DMSG("Exceed block size, update len to %zd bytes",
1223 			bytes_to_read);
1224 	}
1225 	memcpy(buf, b->data + offset, bytes_to_read);
1226 }
1227 
1228 #ifdef CFG_FS_BLOCK_CACHE
1229 static struct block *read_block_with_cache(struct tee_fs_fd *fdp, int block_num)
1230 {
1231 	struct block *b;
1232 
1233 	get_block_from_cache(&fdp->block_cache, block_num, &b);
1234 	if (is_block_data_invalid(b))
1235 		if (read_block_from_storage(fdp, b)) {
1236 			EMSG("Unable to read block%d from storage",
1237 					block_num);
1238 			return NULL;
1239 		}
1240 
1241 	return b;
1242 }
1243 #else
1244 
1245 static struct mutex block_mutex = MUTEX_INITIALIZER;
1246 static struct block *read_block_no_cache(struct tee_fs_fd *fdp, int block_num)
1247 {
1248 	static struct block *b;
1249 	int res;
1250 
1251 	mutex_lock(&block_mutex);
1252 	if (!b)
1253 		b = alloc_block();
1254 	b->block_num = block_num;
1255 
1256 	res = read_block_from_storage(fdp, b);
1257 	if (res)
1258 		EMSG("Unable to read block%d from storage",
1259 				block_num);
1260 	mutex_unlock(&block_mutex);
1261 
1262 	return res ? NULL : b;
1263 }
1264 #endif
1265 
1266 static struct block_operations block_ops = {
1267 #ifdef CFG_FS_BLOCK_CACHE
1268 	.read = read_block_with_cache,
1269 #else
1270 	.read = read_block_no_cache,
1271 #endif
1272 	.write = flush_block_to_storage,
1273 };
1274 
1275 static int out_of_place_write(struct tee_fs_fd *fdp, const void *buf,
1276 		size_t len, struct tee_fs_file_meta *new_meta)
1277 {
1278 	int start_block_num = pos_to_block_num(fdp->pos);
1279 	int end_block_num = pos_to_block_num(fdp->pos + len - 1);
1280 	size_t remain_bytes = len;
1281 	uint8_t *data_ptr = (uint8_t *)buf;
1282 	int orig_pos = fdp->pos;
1283 
1284 	while (start_block_num <= end_block_num) {
1285 		int offset = fdp->pos % BLOCK_FILE_SIZE;
1286 		struct block *b;
1287 		size_t size_to_write = (remain_bytes > BLOCK_FILE_SIZE) ?
1288 			BLOCK_FILE_SIZE : remain_bytes;
1289 
1290 		if (size_to_write + offset > BLOCK_FILE_SIZE)
1291 			size_to_write = BLOCK_FILE_SIZE - offset;
1292 
1293 		b = block_ops.read(fdp, start_block_num);
1294 		if (!b)
1295 			goto failed;
1296 
1297 		DMSG("Write data, offset: %d, size_to_write: %zd",
1298 			offset, size_to_write);
1299 		write_data_to_block(b, offset, data_ptr, size_to_write);
1300 
1301 		if (block_ops.write(fdp, b, new_meta)) {
1302 			EMSG("Unable to wrtie block%d to storage",
1303 					b->block_num);
1304 			goto failed;
1305 		}
1306 
1307 		data_ptr += size_to_write;
1308 		remain_bytes -= size_to_write;
1309 		start_block_num++;
1310 		fdp->pos += size_to_write;
1311 	}
1312 
1313 	if (fdp->pos > (tee_fs_off_t)new_meta->info.length)
1314 		new_meta->info.length = fdp->pos;
1315 
1316 	return 0;
1317 failed:
1318 	fdp->pos = orig_pos;
1319 	return -1;
1320 }
1321 
1322 static inline int create_hard_link(const char *old_dir,
1323 			const char *new_dir,
1324 			const char *filename)
1325 {
1326 	char old_path[REE_FS_NAME_MAX];
1327 	char new_path[REE_FS_NAME_MAX];
1328 
1329 	snprintf(old_path, REE_FS_NAME_MAX, "%s/%s",
1330 			old_dir, filename);
1331 	snprintf(new_path, REE_FS_NAME_MAX, "%s/%s",
1332 			new_dir, filename);
1333 
1334 	DMSG("%s -> %s", old_path, new_path);
1335 	return ree_fs_link(old_path, new_path);
1336 }
1337 
1338 static int unlink_tee_file(const char *file)
1339 {
1340 	int res = -1;
1341 	size_t len = strlen(file) + 1;
1342 	struct tee_fs_dirent *dirent;
1343 	struct tee_fs_dir *dir;
1344 
1345 	DMSG("file=%s", file);
1346 
1347 	if (len > TEE_FS_NAME_MAX)
1348 		goto exit;
1349 
1350 	dir = tee_fs_common_opendir(file);
1351 	if (!dir)
1352 		goto exit;
1353 
1354 	dirent = tee_fs_common_readdir(dir);
1355 	while (dirent) {
1356 		char path[REE_FS_NAME_MAX];
1357 
1358 		snprintf(path, REE_FS_NAME_MAX, "%s/%s",
1359 			file, dirent->d_name);
1360 
1361 		DMSG("unlink %s", path);
1362 		res = ree_fs_unlink(path);
1363 		if (res) {
1364 			tee_fs_common_closedir(dir);
1365 			goto exit;
1366 		}
1367 
1368 		dirent = tee_fs_common_readdir(dir);
1369 	}
1370 
1371 	res = tee_fs_common_closedir(dir);
1372 	if (res)
1373 		goto exit;
1374 
1375 	res = tee_fs_common_rmdir(file);
1376 exit:
1377 	return res;
1378 }
1379 
1380 static bool is_tee_file_exist(const char *file)
1381 {
1382 	char meta_path[REE_FS_NAME_MAX];
1383 
1384 	get_meta_filepath(file, 0, meta_path);
1385 	if (ree_fs_access(meta_path, TEE_FS_F_OK)) {
1386 		get_meta_filepath(file, 1, meta_path);
1387 		if (ree_fs_access(meta_path, TEE_FS_F_OK))
1388 			return false;
1389 	}
1390 
1391 	return true;
1392 }
1393 
1394 static struct tee_fs_file_meta *create_tee_file(const char *file)
1395 {
1396 	struct tee_fs_file_meta *meta = NULL;
1397 	int res;
1398 
1399 	DMSG("Creating TEE file=%s", file);
1400 
1401 	/* create TEE file directory if not exist */
1402 	if (ree_fs_access(file, TEE_FS_F_OK)) {
1403 		res = ree_fs_mkdir(file,
1404 				TEE_FS_S_IRUSR | TEE_FS_S_IWUSR);
1405 		if (res) {
1406 			EMSG("Failed to create TEE file directory, res=%d",
1407 				res);
1408 			goto exit;
1409 		}
1410 	}
1411 
1412 	/* create meta file in TEE file directory */
1413 	meta = create_meta_file(file);
1414 	if (!meta)
1415 		EMSG("Failed to create new meta file");
1416 
1417 exit:
1418 	return meta;
1419 }
1420 
1421 static struct tee_fs_file_meta *open_tee_file(const char *file)
1422 {
1423 	struct tee_fs_file_meta *meta = NULL;
1424 	int backup_version = 0;
1425 
1426 	DMSG("Opening TEE file=%s", file);
1427 
1428 	meta = open_meta_file(file, backup_version);
1429 	if (!meta) {
1430 		meta = open_meta_file(file, !backup_version);
1431 		if (!meta) {
1432 			/*
1433 			 * cannot open meta file, assumed the TEE file
1434 			 * is corrupted
1435 			 */
1436 			EMSG("Can not open meta file");
1437 		}
1438 	}
1439 
1440 	return meta;
1441 }
1442 
1443 static struct tee_fs_fd *tee_fs_fd_lookup(int fd)
1444 {
1445 	return handle_lookup(&fs_handle_db, fd);
1446 }
1447 
1448 int tee_fs_common_open(TEE_Result *errno, const char *file, int flags, ...)
1449 {
1450 	int res = -1;
1451 	size_t len;
1452 	struct tee_fs_file_meta *meta = NULL;
1453 	struct tee_fs_fd *fdp = NULL;
1454 	bool file_exist;
1455 
1456 	assert(errno != NULL);
1457 	*errno = TEE_SUCCESS;
1458 
1459 	if (!file) {
1460 		*errno = TEE_ERROR_BAD_PARAMETERS;
1461 		goto exit;
1462 	}
1463 
1464 	len = strlen(file) + 1;
1465 	if (len > TEE_FS_NAME_MAX) {
1466 		*errno = TEE_ERROR_BAD_PARAMETERS;
1467 		goto exit;
1468 	}
1469 
1470 	file_exist = is_tee_file_exist(file);
1471 	if (flags & TEE_FS_O_CREATE) {
1472 		if ((flags & TEE_FS_O_EXCL) && file_exist) {
1473 			EMSG("tee file already exists");
1474 			*errno = TEE_ERROR_ACCESS_CONFLICT;
1475 			goto exit;
1476 		}
1477 
1478 		if (!file_exist)
1479 			meta = create_tee_file(file);
1480 		else
1481 			meta = open_tee_file(file);
1482 
1483 	} else {
1484 		if (!file_exist) {
1485 			EMSG("tee file not exists");
1486 			*errno = TEE_ERROR_ITEM_NOT_FOUND;
1487 			goto exit;
1488 		}
1489 
1490 		meta = open_tee_file(file);
1491 	}
1492 
1493 	if (!meta) {
1494 		EMSG("Failed to open TEE file");
1495 		*errno = TEE_ERROR_CORRUPT_OBJECT;
1496 		goto exit;
1497 	}
1498 
1499 	DMSG("file=%s, length=%zd", file, meta->info.length);
1500 	fdp = (struct tee_fs_fd *)malloc(sizeof(struct tee_fs_fd));
1501 	if (!fdp) {
1502 		*errno = TEE_ERROR_OUT_OF_MEMORY;
1503 		goto exit_free_meta;
1504 	}
1505 
1506 	/* init internal status */
1507 	fdp->flags = flags;
1508 	fdp->meta = meta;
1509 	fdp->pos = 0;
1510 	if (init_block_cache(&fdp->block_cache)) {
1511 		res = -1;
1512 		goto exit_free_fd;
1513 	}
1514 
1515 	fdp->filename = malloc(len);
1516 	if (!fdp->filename) {
1517 		res = -1;
1518 		*errno = TEE_ERROR_OUT_OF_MEMORY;
1519 		goto exit_destroy_block_cache;
1520 	}
1521 	memcpy(fdp->filename, file, len);
1522 
1523 	if ((flags & TEE_FS_O_TRUNC) &&
1524 		(flags & TEE_FS_O_WRONLY || flags & TEE_FS_O_RDWR)) {
1525 		res = tee_fs_common_ftruncate(errno, fdp, 0);
1526 		if (res < 0) {
1527 			EMSG("Unable to truncate file");
1528 			goto exit_free_filename;
1529 		}
1530 	}
1531 
1532 	/* return fd */
1533 	res = handle_get(&fs_handle_db, fdp);
1534 	if (res < 0)
1535 		goto exit_free_filename;
1536 	fdp->fd = res;
1537 	goto exit;
1538 
1539 exit_free_filename:
1540 	free(fdp->filename);
1541 exit_destroy_block_cache:
1542 	destroy_block_cache(&fdp->block_cache);
1543 exit_free_fd:
1544 	free(fdp);
1545 exit_free_meta:
1546 	free(meta);
1547 exit:
1548 	return res;
1549 }
1550 
1551 int tee_fs_common_close(struct tee_fs_fd *fdp)
1552 {
1553 	int res = -1;
1554 
1555 	if (!fdp)
1556 		return -1;
1557 
1558 	handle_put(&fs_handle_db, fdp->fd);
1559 
1560 	destroy_block_cache(&fdp->block_cache);
1561 	free(fdp->meta);
1562 	free(fdp->filename);
1563 	free(fdp);
1564 
1565 	return res;
1566 }
1567 
1568 tee_fs_off_t tee_fs_common_lseek(TEE_Result *errno, struct tee_fs_fd *fdp,
1569 				tee_fs_off_t offset, int whence)
1570 {
1571 	tee_fs_off_t res = -1;
1572 	tee_fs_off_t new_pos;
1573 	size_t filelen;
1574 
1575 	assert(errno != NULL);
1576 	*errno = TEE_SUCCESS;
1577 
1578 	if (!fdp) {
1579 		*errno = TEE_ERROR_BAD_PARAMETERS;
1580 		goto exit;
1581 	}
1582 
1583 	DMSG("offset=%d, whence=%d", (int)offset, whence);
1584 
1585 	filelen = fdp->meta->info.length;
1586 
1587 	switch (whence) {
1588 	case TEE_FS_SEEK_SET:
1589 		new_pos = offset;
1590 		break;
1591 
1592 	case TEE_FS_SEEK_CUR:
1593 		new_pos = fdp->pos + offset;
1594 		break;
1595 
1596 	case TEE_FS_SEEK_END:
1597 		new_pos = filelen + offset;
1598 		break;
1599 
1600 	default:
1601 		*errno = TEE_ERROR_BAD_PARAMETERS;
1602 		goto exit;
1603 	}
1604 
1605 	if (new_pos < 0)
1606 		new_pos = 0;
1607 
1608 	if (new_pos > TEE_DATA_MAX_POSITION) {
1609 		EMSG("Position is beyond TEE_DATA_MAX_POSITION");
1610 		*errno = TEE_ERROR_BAD_PARAMETERS;
1611 		goto exit;
1612 	}
1613 
1614 	res = fdp->pos = new_pos;
1615 exit:
1616 	return res;
1617 }
1618 
1619 /*
1620  * To ensure atomic truncate operation, we can:
1621  *
1622  *  - update file length to new length
1623  *  - commit new meta
1624  *  - free unused blocks
1625  *
1626  * To ensure atomic extend operation, we can:
1627  *
1628  *  - update file length to new length
1629  *  - allocate and fill zero data to new blocks
1630  *  - commit new meta
1631  *
1632  * Any failure before committing new meta is considered as
1633  * update failed, and the file content will not be updated
1634  */
1635 int tee_fs_common_ftruncate(TEE_Result *errno, struct tee_fs_fd *fdp,
1636 				tee_fs_off_t new_file_len)
1637 {
1638 	int res = -1;
1639 	size_t old_file_len = fdp->meta->info.length;
1640 	struct tee_fs_file_meta *new_meta = NULL;
1641 	uint8_t *buf = NULL;
1642 
1643 	assert(errno != NULL);
1644 	*errno = TEE_SUCCESS;
1645 
1646 	if (!fdp) {
1647 		*errno = TEE_ERROR_BAD_PARAMETERS;
1648 		res = -1;
1649 		goto exit;
1650 	}
1651 
1652 	if (fdp->flags & TEE_FS_O_RDONLY) {
1653 		*errno = TEE_ERROR_BAD_PARAMETERS;
1654 		EMSG("Read only");
1655 		res = -1;
1656 		goto exit;
1657 	}
1658 
1659 	if ((size_t)new_file_len == old_file_len) {
1660 		DMSG("Ignore due to file length does not changed");
1661 		res = 0;
1662 		goto exit;
1663 	}
1664 
1665 	if (new_file_len > MAX_FILE_SIZE) {
1666 		*errno = TEE_ERROR_BAD_PARAMETERS;
1667 		EMSG("Over maximum file size(%d)", MAX_FILE_SIZE);
1668 		res = -1;
1669 		goto exit;
1670 	}
1671 
1672 	new_meta = duplicate_meta(fdp);
1673 	if (!new_meta) {
1674 		*errno = TEE_ERROR_OUT_OF_MEMORY;
1675 		res = -1;
1676 		goto free;
1677 	}
1678 
1679 	new_meta->info.length = new_file_len;
1680 
1681 	if ((size_t)new_file_len < old_file_len) {
1682 		int old_block_num = get_last_block_num(old_file_len);
1683 		int new_block_num = get_last_block_num(new_file_len);
1684 
1685 		DMSG("Truncate file length to %zu", (size_t)new_file_len);
1686 
1687 		res = commit_meta_file(fdp, new_meta);
1688 		if (res < 0) {
1689 			*errno = TEE_ERROR_CORRUPT_OBJECT;
1690 			EMSG("Failed to commit meta file");
1691 			goto free;
1692 		}
1693 
1694 		/* now we are safe to free unused blocks */
1695 		while (old_block_num > new_block_num) {
1696 			if (remove_block_file(fdp, old_block_num)) {
1697 				IMSG("Warning: Failed to free block: %d",
1698 						old_block_num);
1699 			}
1700 
1701 			old_block_num--;
1702 		}
1703 
1704 	} else {
1705 		size_t ext_len = new_file_len - old_file_len;
1706 		int orig_pos = fdp->pos;
1707 
1708 		buf = malloc(BLOCK_FILE_SIZE);
1709 		if (!buf) {
1710 			*errno = TEE_ERROR_OUT_OF_MEMORY;
1711 			EMSG("Failed to allocate buffer, size=%d",
1712 					BLOCK_FILE_SIZE);
1713 			res = -1;
1714 			goto free;
1715 		}
1716 
1717 		memset(buf, 0x0, BLOCK_FILE_SIZE);
1718 
1719 		DMSG("Extend file length to %zu", (size_t)new_file_len);
1720 
1721 		fdp->pos = old_file_len;
1722 
1723 		res = 0;
1724 		while (ext_len > 0) {
1725 			size_t data_len = (ext_len > BLOCK_FILE_SIZE) ?
1726 					BLOCK_FILE_SIZE : ext_len;
1727 
1728 			DMSG("fill len=%zu", data_len);
1729 			res = out_of_place_write(fdp, (void *)buf,
1730 					data_len, new_meta);
1731 			if (res < 0) {
1732 				*errno = TEE_ERROR_CORRUPT_OBJECT;
1733 				EMSG("Failed to fill data");
1734 				break;
1735 			}
1736 
1737 			ext_len -= data_len;
1738 		}
1739 
1740 		fdp->pos = orig_pos;
1741 
1742 		if (res == 0) {
1743 			res = commit_meta_file(fdp, new_meta);
1744 			if (res < 0) {
1745 				*errno = TEE_ERROR_CORRUPT_OBJECT;
1746 				EMSG("Failed to commit meta file");
1747 			}
1748 		}
1749 	}
1750 
1751 free:
1752 	free(new_meta);
1753 	free(buf);
1754 
1755 exit:
1756 	return res;
1757 }
1758 
1759 int tee_fs_common_read(TEE_Result *errno, struct tee_fs_fd *fdp,
1760 		       void *buf, size_t len)
1761 {
1762 	int res = -1;
1763 	int start_block_num;
1764 	int end_block_num;
1765 	size_t remain_bytes = len;
1766 	uint8_t *data_ptr = buf;
1767 
1768 	assert(errno != NULL);
1769 	*errno = TEE_SUCCESS;
1770 
1771 	if (!fdp) {
1772 		*errno = TEE_ERROR_BAD_PARAMETERS;
1773 		goto exit;
1774 	}
1775 
1776 	if (fdp->pos + len > fdp->meta->info.length) {
1777 		len = fdp->meta->info.length - fdp->pos;
1778 		DMSG("reached EOF, update read length to %zu", len);
1779 	}
1780 
1781 	if (!len) {
1782 		res = 0;
1783 		goto exit;
1784 	}
1785 
1786 	if (!buf) {
1787 		*errno = TEE_ERROR_BAD_PARAMETERS;
1788 		goto exit;
1789 	}
1790 
1791 	if (fdp->flags & TEE_FS_O_WRONLY) {
1792 		*errno = TEE_ERROR_ACCESS_CONFLICT;
1793 		goto exit;
1794 	}
1795 
1796 	DMSG("%s, data len=%zu", fdp->filename, len);
1797 
1798 	start_block_num = pos_to_block_num(fdp->pos);
1799 	end_block_num = pos_to_block_num(fdp->pos + len - 1);
1800 	DMSG("start_block_num:%d, end_block_num:%d",
1801 		start_block_num, end_block_num);
1802 
1803 	while (start_block_num <= end_block_num) {
1804 		struct block *b;
1805 		int offset = fdp->pos % BLOCK_FILE_SIZE;
1806 		size_t size_to_read = remain_bytes > BLOCK_FILE_SIZE ?
1807 			BLOCK_FILE_SIZE : remain_bytes;
1808 
1809 		if (size_to_read + offset > BLOCK_FILE_SIZE)
1810 			size_to_read = BLOCK_FILE_SIZE - offset;
1811 
1812 		DMSG("block_num:%d, offset:%d, size_to_read: %zd",
1813 			start_block_num, offset, size_to_read);
1814 
1815 		b = block_ops.read(fdp, start_block_num);
1816 		if (!b) {
1817 			*errno = TEE_ERROR_CORRUPT_OBJECT;
1818 			goto exit;
1819 		}
1820 
1821 		read_data_from_block(b, offset, data_ptr, size_to_read);
1822 		data_ptr += size_to_read;
1823 		remain_bytes -= size_to_read;
1824 		fdp->pos += size_to_read;
1825 
1826 		start_block_num++;
1827 	}
1828 	res = 0;
1829 exit:
1830 	return (res < 0) ? res : (int)len;
1831 }
1832 
1833 /*
1834  * To ensure atomicity of write operation, we need to
1835  * do the following steps:
1836  * (The sequence of operations is very important)
1837  *
1838  *  - Create a new backup version of meta file as a copy
1839  *    of current meta file.
1840  *  - For each blocks to write:
1841  *    - Create new backup version for current block.
1842  *    - Write data to new backup version.
1843  *    - Update the new meta file accordingly.
1844  *  - Write the new meta file.
1845  *
1846  * (Any failure in above steps is considered as update failed,
1847  *  and the file content will not be updated)
1848  *
1849  * After previous step the update is considered complete, but
1850  * we should do the following clean-up step(s):
1851  *
1852  *  - Delete old meta file.
1853  *  - Remove old block files.
1854  *
1855  * (Any failure in above steps is considered as a successfully
1856  *  update)
1857  */
1858 int tee_fs_common_write(TEE_Result *errno, struct tee_fs_fd *fdp,
1859 			const void *buf, size_t len)
1860 {
1861 	int res = -1;
1862 	struct tee_fs_file_meta *new_meta = NULL;
1863 	size_t file_size = fdp->meta->info.length;
1864 	int orig_pos = fdp->pos;
1865 
1866 	assert(errno != NULL);
1867 	*errno = TEE_SUCCESS;
1868 
1869 	if (!fdp) {
1870 		*errno = TEE_ERROR_BAD_PARAMETERS;
1871 		goto exit;
1872 	}
1873 
1874 	if (!len) {
1875 		res = 0;
1876 		goto exit;
1877 	}
1878 
1879 	if (!buf) {
1880 		*errno = TEE_ERROR_BAD_PARAMETERS;
1881 		goto exit;
1882 	}
1883 
1884 	if (fdp->flags & TEE_FS_O_RDONLY) {
1885 		EMSG("Write to a read-only file, denied");
1886 		*errno = TEE_ERROR_ACCESS_CONFLICT;
1887 		goto exit;
1888 	}
1889 
1890 	if ((fdp->pos + len) > MAX_FILE_SIZE) {
1891 		EMSG("Over maximum file size(%d)", MAX_FILE_SIZE);
1892 		*errno = TEE_ERROR_BAD_PARAMETERS;
1893 		goto exit;
1894 	}
1895 
1896 	DMSG("%s, data len=%zu", fdp->filename, len);
1897 	if (file_size < (size_t)fdp->pos) {
1898 		DMSG("File hole detected, try to extend file size");
1899 		res = tee_fs_common_ftruncate(errno, fdp, fdp->pos);
1900 		if (res < 0)
1901 			goto exit;
1902 	}
1903 
1904 	new_meta = duplicate_meta(fdp);
1905 	if (!new_meta) {
1906 		*errno = TEE_ERROR_OUT_OF_MEMORY;
1907 		goto exit;
1908 	}
1909 
1910 	res = out_of_place_write(fdp, buf, len, new_meta);
1911 	if (res < 0) {
1912 		*errno = TEE_ERROR_CORRUPT_OBJECT;
1913 	} else {
1914 		int r;
1915 		int start_block_num;
1916 		int end_block_num;
1917 
1918 		r = commit_meta_file(fdp, new_meta);
1919 		if (r < 0) {
1920 			*errno = TEE_ERROR_CORRUPT_OBJECT;
1921 			res = -1;
1922 		}
1923 
1924 		/* we are safe to free old blocks */
1925 		start_block_num = pos_to_block_num(orig_pos);
1926 		end_block_num = pos_to_block_num(fdp->pos - 1);
1927 		while (start_block_num <= end_block_num) {
1928 			if (remove_outdated_block(fdp, start_block_num))
1929 				IMSG("Warning: Failed to free old block: %d",
1930 					start_block_num);
1931 
1932 			start_block_num++;
1933 		}
1934 	}
1935 exit:
1936 	free(new_meta);
1937 	return (res < 0) ? res : (int)len;
1938 }
1939 
1940 /*
1941  * To ensure atomicity of rename operation, we need to
1942  * do the following steps:
1943  *
1944  *  - Create a new folder that represents the renamed TEE file
1945  *  - For each REE block files, create a hard link under the just
1946  *    created folder (new TEE file)
1947  *  - Now we are ready to commit meta, create hard link for the
1948  *    meta file
1949  *
1950  * (Any failure in above steps is considered as update failed,
1951  *  and the file content will not be updated)
1952  *
1953  * After previous step the update is considered complete, but
1954  * we should do the following clean-up step(s):
1955  *
1956  *  - Unlink all REE files represents the old TEE file (including
1957  *    meta and block files)
1958  *
1959  * (Any failure in above steps is considered as a successfully
1960  *  update)
1961  */
1962 int tee_fs_common_rename(const char *old, const char *new)
1963 {
1964 	int res = -1;
1965 	size_t old_len;
1966 	size_t new_len;
1967 	size_t meta_count = 0;
1968 	struct tee_fs_dir *old_dir;
1969 	struct tee_fs_dirent *dirent;
1970 	char *meta_filename = NULL;
1971 
1972 	if (!old || !new)
1973 		return -1;
1974 
1975 	DMSG("old=%s, new=%s", old, new);
1976 
1977 	old_len = strlen(old) + 1;
1978 	new_len = strlen(new) + 1;
1979 
1980 	if (old_len > TEE_FS_NAME_MAX || new_len >TEE_FS_NAME_MAX)
1981 		goto exit;
1982 
1983 	res = ree_fs_mkdir(new,
1984 			TEE_FS_S_IRUSR | TEE_FS_S_IWUSR);
1985 	if (res)
1986 		goto exit;
1987 
1988 	old_dir = tee_fs_common_opendir(old);
1989 	if (!old_dir)
1990 		goto exit;
1991 
1992 	dirent = tee_fs_common_readdir(old_dir);
1993 	while (dirent) {
1994 		if (!strncmp(dirent->d_name, "meta.", 5)) {
1995 			meta_filename = strdup(dirent->d_name);
1996 			meta_count++;
1997 		} else {
1998 			res = create_hard_link(old, new, dirent->d_name);
1999 			if (res)
2000 				goto exit_close_old_dir;
2001 		}
2002 
2003 		dirent = tee_fs_common_readdir(old_dir);
2004 	}
2005 
2006 	/* finally, link the meta file, rename operation completed */
2007 	TEE_ASSERT(meta_filename);
2008 
2009 	/*
2010 	 * TODO: This will cause memory leakage at previous strdup()
2011 	 * if we accidently have two meta files in a TEE file.
2012 	 *
2013 	 * It's not easy to handle the case above (e.g. Which meta file
2014 	 * should be linked first? What to do if a power cut happened
2015 	 * during creating links for the two meta files?)
2016 	 *
2017 	 * We will solve this issue using another approach: merging
2018 	 * both meta and block files into a single REE file. This approach
2019 	 * can completely remove tee_fs_common_rename(). We can simply
2020 	 * rename TEE file using REE rename() system call, which is also
2021 	 * atomic.
2022 	 */
2023 	if (meta_count > 1)
2024 		EMSG("Warning: more than one meta file in your TEE file\n"
2025 		     "This will cause memory leakage.");
2026 
2027 	res = create_hard_link(old, new, meta_filename);
2028 	if (res)
2029 		goto exit_close_old_dir;
2030 
2031 	/* we are safe now, remove old TEE file */
2032 	unlink_tee_file(old);
2033 
2034 exit_close_old_dir:
2035 	tee_fs_common_closedir(old_dir);
2036 exit:
2037 	free(meta_filename);
2038 	return res;
2039 }
2040 
2041 /*
2042  * To ensure atomic unlink operation, we can simply
2043  * split the unlink operation into:
2044  *
2045  *  - rename("file", "file.trash");
2046  *
2047  * (Any failure in above steps is considered as update failed,
2048  *  and the file content will not be updated)
2049  *
2050  * After previous step the update is considered complete, but
2051  * we should do the following clean-up step(s):
2052  *
2053  *  - unlink("file.trash");
2054  *
2055  * (Any failure in above steps is considered as a successfully
2056  *  update)
2057  */
2058 int tee_fs_common_unlink(const char *file)
2059 {
2060 	int res = -1;
2061 	char trash_file[TEE_FS_NAME_MAX + 6];
2062 
2063 	if (!file)
2064 		return -1;
2065 
2066 	snprintf(trash_file, TEE_FS_NAME_MAX + 6, "%s.trash",
2067 		file);
2068 
2069 	res = tee_fs_common_rename(file, trash_file);
2070 	if (res < 0)
2071 		return res;
2072 
2073 	unlink_tee_file(trash_file);
2074 
2075 	return res;
2076 }
2077 
2078 int tee_fs_common_mkdir(const char *path, tee_fs_mode_t mode)
2079 {
2080 	return ree_fs_mkdir(path, mode);
2081 }
2082 
2083 tee_fs_dir *tee_fs_common_opendir(const char *name)
2084 {
2085 	return ree_fs_opendir(name);
2086 }
2087 
2088 int tee_fs_common_closedir(tee_fs_dir *d)
2089 {
2090 	return ree_fs_closedir(d);
2091 }
2092 
2093 struct tee_fs_dirent *tee_fs_common_readdir(tee_fs_dir *d)
2094 {
2095 	return ree_fs_readdir(d);
2096 }
2097 
2098 int tee_fs_common_rmdir(const char *name)
2099 {
2100 	return ree_fs_rmdir(name);
2101 }
2102 
2103 int tee_fs_common_access(const char *name, int mode)
2104 {
2105 	return ree_fs_access(name, mode);
2106 }
2107 
2108 static int tee_fs_close(int fd)
2109 {
2110 	struct tee_fs_fd *fdp = tee_fs_fd_lookup(fd);
2111 
2112 	return tee_fs_common_close(fdp);
2113 }
2114 
2115 static int tee_fs_read(TEE_Result *errno, int fd, void *buf, size_t len)
2116 {
2117 	struct tee_fs_fd *fdp = tee_fs_fd_lookup(fd);
2118 
2119 	return tee_fs_common_read(errno, fdp, buf, len);
2120 }
2121 
2122 static int tee_fs_write(TEE_Result *errno, int fd, const void *buf, size_t len)
2123 {
2124 	struct tee_fs_fd *fdp = tee_fs_fd_lookup(fd);
2125 
2126 	return tee_fs_common_write(errno, fdp, buf, len);
2127 }
2128 
2129 static tee_fs_off_t tee_fs_lseek(TEE_Result *errno,
2130 				 int fd, tee_fs_off_t offset, int whence)
2131 {
2132 	struct tee_fs_fd *fdp = tee_fs_fd_lookup(fd);
2133 
2134 	return tee_fs_common_lseek(errno, fdp, offset, whence);
2135 }
2136 
2137 static int tee_fs_ftruncate(TEE_Result *errno, int fd, tee_fs_off_t length)
2138 {
2139 	struct tee_fs_fd *fdp = tee_fs_fd_lookup(fd);
2140 
2141 	return tee_fs_common_ftruncate(errno, fdp, length);
2142 }
2143 
2144 struct tee_file_operations tee_file_ops = {
2145 	.open = tee_fs_common_open,
2146 	.close = tee_fs_close,
2147 	.read = tee_fs_read,
2148 	.write = tee_fs_write,
2149 	.lseek = tee_fs_lseek,
2150 	.ftruncate = tee_fs_ftruncate,
2151 	.rename = tee_fs_common_rename,
2152 	.unlink = tee_fs_common_unlink,
2153 	.mkdir = tee_fs_common_mkdir,
2154 	.opendir = tee_fs_common_opendir,
2155 	.closedir = tee_fs_common_closedir,
2156 	.readdir = tee_fs_common_readdir,
2157 	.rmdir = tee_fs_common_rmdir,
2158 	.access = tee_fs_common_access
2159 };
2160