ree_fs_new_opendir(): ignore empty directory

The behavior of ree_fs_new_opendir() should be the same when a TA
directory does not exist, or when it is empty: return
TEEC_ERROR_ITEM_NOT_FOUND in both cases.

Currently, ree_fs_new_opendir() returns TEE_SUCCESS when the TA
directory exists.  This causes an issue with REE FS, when the data
directory is mounted over NFS. "xtest 6009 6010" fails with
TEE_StartPersistentObjectEnumerator() returning TEE_SUCCESS instead of
TEE_ERROR_ITEM_NOT_FOUND.

This is because test 6009 does not properly clean up. The test creates
persistent objects, closes them, opens them again with the meta accesss
flag and deletes them by calling TEE_CloseAndDeletePersistentObject1().
It turns out that tee-supplicant *does* attempt to remove the directory
but receives error ENOTEMPTY when the filesystem is NFS-mounted. The
reason is that when it removes the file, as a consequence of
syscall_storage_obj_del() calling o->pobj->fops->remove(o->pobj),
tee-supplicant still has an open file descriptor to the object. This
causes the NFS server to keep a hidden file (.nfsXXX) in the directory,
causing the subsequent rmdir() to fail. Then, when
syscall_storage_obj_del() calls tee_obj_close(), the fd is closed and
the .nfsXXX file disappears. We're left with an empty TA directory, and
when TEE_StartPersistentObjectEnumerator() invokes ree_fs_new_opendir()
it ends up with TEE_SUCCESS instead of TEE_ERROR_ITEM_NOT_FOUND.

One option to fix the issue is to fix the directory cleanup sequence,
i.e., make sure that the file descriptor is closed before the file is
unlinked and the directory removed. But we choose to adjust
ree_fs_new_opendir() instead, because it is less intrusive in OP-TEE OS
and also because the secure storage code is being reworked anyway for
other reasons.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
1 file changed
tree: eb11c3ae9a5bddefdaef0d8af9c94d0fe55b15fd
  1. libsqlfs/
  2. libsqlite3/
  3. libteec/
  4. public/
  5. tee-supplicant/
  6. .gitignore
  7. .travis.yml
  8. Android.mk
  9. android_flags.mk
  10. config.mk
  11. flags.mk
  12. LICENSE
  13. Makefile
  14. Notice.md
  15. README.md
README.md

OP-TEE Client API

The optee-client git, containing the source code for the TEE client library in Linux. This component provides the TEE Client API as defined by the GlobalPlatform TEE standard. It is distributed under the BSD 2-clause open-source license. For a general overview of OP-TEE, please see the Notice.md file.

In this git there are two main target/binaries to build. There is libteec.so, which is the library that contains that API for communication with the Trusted OS. Then the other target is the binary tee-supplicant which is a daemon serving the Trusted OS in secure world with miscellaneous features, such as file system access.

License

The software is provided under the BSD 2-Clause license.

Platforms supported

This software in this git doesn't directly have any dependencies to any particular hardware, since it's pure software library directly communicating with the Linux kernel. Currently the software has been tested using:

  • STMicroelectronics b2020-h416 (orly-2) hardware (32-bits)
  • Some initial testing has been done using Foundation FVP, which can be downloaded free of charge.

Get and build the software

Get the compiler

We will strive to use the latest available compiler from Linaro. This file refers to a list of toolchains we have used and know are working in our setups. Start by downloading and unpacking a compiler from it. Then export the PATH to the bin folder.

$ cd $HOME
$ mkdir toolchains
$ cd toolchains
$ wget [url/to/gcc_tarball]
$ tar xvf [gcc_tarball]
$ export PATH=$HOME/toolchains/[gcc_extracted_dir]/bin:$PATH

Download the source code

$ cd $HOME
$ mkdir devel
$ cd devel
$ git clone https://github.com/OP-TEE/optee_client.git

Build

$ cd $HOME/devel/optee_client
$ make

For a 64-bit build:

$ make CROSS_COMPILE=aarch64-linux-gnu-

Compiler flags

To be able to see the full command when building you could build using following flag:

$ make V=1

Coding standards

In this project we are trying to adhere to the same coding convention as used in the Linux kernel (see CodingStyle). We achieve this by running checkpatch from Linux kernel. However there are a few exceptions that we had to make since the code also follows GlobalPlatform standards. The exceptions are as follows:

  • CamelCase for GlobalPlatform types are allowed.
  • And we also exclude checking third party code that we might use in this project, such as LibTomCrypt, MPA, newlib (not in this particular git, but those are also part of the complete TEE solution). The reason for excluding and not fixing third party code is because we would probably deviate too much from upstream and therefore it would be hard to rebase against those projects later on (and we don't expect that it is easy to convince other software projects to change coding style).

checkpatch

Since checkpatch is licensed under the terms of GNU GPL License Version 2, we cannot include this script directly into this project. Therefore we have written the Makefile so you need to explicitly point to the script by exporting an environment variable, namely CHECKPATCH. So, suppose that the source code for the Linux kernel is at $HOME/devel/linux, then you have to export like follows:

$ export CHECKPATCH=$HOME/devel/linux/scripts/checkpatch.pl

thereafter it should be possible to use one of the different checkpatch targets in the Makefile. There are targets for checking all files, checking against latest commit, against a certain base-commit etc. For the details, read the Makefile.