From 5bc3a96dbd602fe4a7d763332d3e23afca02257e Mon Sep 17 00:00:00 2001 From: "Wiktor S. Ovalle Correa" Date: Thu, 14 Jan 2021 17:55:38 +0100 Subject: [PATCH] [EGD-4551] Add missing read() interception Fix error caused by libstdc++ passing our fd to native read() --- board/linux/libiosyscalls/CMakeLists.txt | 4 +++ .../libiosyscalls/include/iosyscalls.hpp | 3 +- board/linux/libiosyscalls/src/iosyscalls.cpp | 10 ++++-- .../libiosyscalls/src/syscalls_posix.cpp | 31 ++++++++++++---- .../libiosyscalls/src/syscalls_stdio.cpp | 2 +- board/linux/libiosyscalls/test/CMakeLists.txt | 13 +++++++ .../libiosyscalls/test/unittest_iosys.cpp | 36 +++++++++++++++++++ board/linux/libiosyscalls/version.txt | 2 +- 8 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 board/linux/libiosyscalls/test/CMakeLists.txt create mode 100644 board/linux/libiosyscalls/test/unittest_iosys.cpp diff --git a/board/linux/libiosyscalls/CMakeLists.txt b/board/linux/libiosyscalls/CMakeLists.txt index 4088b485f250c64dcd77a7da06db565481735aaa..b30266ea86b09a1bb19dc85b73056bc4f9418d7a 100644 --- a/board/linux/libiosyscalls/CMakeLists.txt +++ b/board/linux/libiosyscalls/CMakeLists.txt @@ -43,3 +43,7 @@ target_link_options(${PROJECT_NAME} PRIVATE target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDES} ) target_link_libraries( ${PROJECT_NAME} dl ) target_compile_definitions( ${PROJECT_NAME} PUBLIC TARGET_Linux ) + +if (${ENABLE_TESTS}) + add_subdirectory(test) +endif () diff --git a/board/linux/libiosyscalls/include/iosyscalls.hpp b/board/linux/libiosyscalls/include/iosyscalls.hpp index 36db947b6715b713da368e4529a6544291bf90d6..8dee370538d3c64b2e670d1994da7370faa577bd 100644 --- a/board/linux/libiosyscalls/include/iosyscalls.hpp +++ b/board/linux/libiosyscalls/include/iosyscalls.hpp @@ -22,7 +22,8 @@ namespace vfsn::linux::internal int ungetchar {-1}; }; - int get_native_fd(FILEX*); + int to_native_fd(int fd); + int to_image_fd(int fd); FILEX* allocate_filex(int fd); bool is_filex(const void* fd); diff --git a/board/linux/libiosyscalls/src/iosyscalls.cpp b/board/linux/libiosyscalls/src/iosyscalls.cpp index 7ea05fb54b17298f14583c997ac9e267ccf6fe41..3b81258a52df2084317a8f8bfeed90183b1ae40d 100644 --- a/board/linux/libiosyscalls/src/iosyscalls.cpp +++ b/board/linux/libiosyscalls/src/iosyscalls.cpp @@ -27,6 +27,7 @@ namespace { "/proc", "/dev/shm", "PurePhone.img", + "MuditaOS.log", nullptr, }; constexpr const char * EXCLUDED_PATHS[] = { @@ -104,9 +105,14 @@ namespace vfsn::linux::internal return false; } - int get_native_fd(FILEX* file) + int to_native_fd(int fd) { - return file ? (FIRST_FILEDESC + file->fd) : -1; + return FIRST_FILEDESC + fd; + } + + int to_image_fd(int fd) + { + return fd - FIRST_FILEDESC; } bool is_image_fd(int fd) diff --git a/board/linux/libiosyscalls/src/syscalls_posix.cpp b/board/linux/libiosyscalls/src/syscalls_posix.cpp index f4a74c9532a9d3747050843790e1890452824aa4..9ef4962946c1174136a2e2881ff1246dcc05ba73 100644 --- a/board/linux/libiosyscalls/src/syscalls_posix.cpp +++ b/board/linux/libiosyscalls/src/syscalls_posix.cpp @@ -50,6 +50,8 @@ namespace __REAL_DECL(__xstat64); __REAL_DECL(__lxstat64); __REAL_DECL(__fxstat64); + + __REAL_DECL(read); } // namespace real void __attribute__((constructor)) _lib_posix_initialize() @@ -82,13 +84,15 @@ namespace __REAL_DLSYM(__lxstat64); __REAL_DLSYM(__fxstat64); + __REAL_DLSYM(read); if (!(real::link && real::unlink && real::symlink && real::fcntl && real::fcntl64 && real::chdir && real::fchdir && real::getcwd && real::getwd && real::get_current_dir_name && real::mkdir && real::chmod && real::fchmod && real::fsync && real::fdatasync && real::__xstat && real::__lxstat && real::__fxstat - && real::__xstat64 && real::__lxstat64 && real::__fxstat64)) + && real::__xstat64 && real::__lxstat64 && real::__fxstat64 + && real::read)) { abort(); } @@ -99,6 +103,19 @@ extern "C" { namespace vfs = vfsn::linux::internal; using fs = purefs::fs::filesystem; + int _iosys_read(int __fd, void *__buf, size_t __nbyte) + { + if (vfs::is_image_fd(__fd)) + { + TRACE_SYSCALLN("(%d) -> VFS", __fd); + return vfs::invoke_fs(&fs::read,vfs::to_image_fd(__fd),(char*)__buf,__nbyte); + } else { + TRACE_SYSCALLN("(%d) -> linux fs", __fd); + return real::read(__fd, __buf, __nbyte); + } + } + __asm__(".symver _iosys_read,read@GLIBC_2.2.5"); + int _iosys_link(const char *oldpath, const char *newpath) { if(vfs::redirect_to_image(oldpath)) @@ -175,7 +192,7 @@ extern "C" { if(vfs::is_image_fd(fd)) { TRACE_SYSCALLN("(%d) -> VFS", fd); - return vfs::invoke_fs(&fs::fstat,fd,*pstat); + return vfs::invoke_fs(&fs::fstat,vfs::to_image_fd(fd),*pstat); } else { @@ -371,7 +388,7 @@ extern "C" { if(vfs::is_image_fd(fd)) { TRACE_SYSCALLN("(%d) -> VFS", fd); - return vfs::invoke_fs(&fs::fchmod,fd,mode); + return vfs::invoke_fs(&fs::fchmod,vfs::to_image_fd(fd),mode); } else { @@ -386,7 +403,7 @@ extern "C" { if(vfs::is_image_fd(fd)) { TRACE_SYSCALLN("(%d) -> VFS", fd); - return vfs::invoke_fs(&fs::fsync, fd); + return vfs::invoke_fs(&fs::fsync, vfs::to_image_fd(fd)); } else { @@ -401,7 +418,7 @@ extern "C" { if(vfs::is_image_fd(fd)) { TRACE_SYSCALLN("(%d) -> VFS", fd); - return vfs::invoke_fs(&fs::fsync, fd); + return vfs::invoke_fs(&fs::fsync, vfs::to_image_fd(fd)); } else { @@ -468,7 +485,7 @@ extern "C" { if(vfs::is_image_fd(fildes)) { TRACE_SYSCALLN("(%d) -> VFS", fildes); - return vfs::invoke_fs(&fs::fstat, fildes, *stat_buf); + return vfs::invoke_fs(&fs::fstat, vfs::to_image_fd(fildes), *stat_buf); } else { @@ -525,7 +542,7 @@ extern "C" { if(vfs::is_image_fd(fildes)) { TRACE_SYSCALLN("(%d) -> VFS", fildes); - return vfs::invoke_fs(&fs::fstat, fildes, *(struct stat*)stat_buf); + return vfs::invoke_fs(&fs::fstat, vfs::to_image_fd(fildes), *(struct stat*)stat_buf); } else { diff --git a/board/linux/libiosyscalls/src/syscalls_stdio.cpp b/board/linux/libiosyscalls/src/syscalls_stdio.cpp index 4a0d3183a40ab80325ed2af0012745953dcb54cb..e7cc8283672c41ee0b3b974c8f2dfe2bfc118c0b 100644 --- a/board/linux/libiosyscalls/src/syscalls_stdio.cpp +++ b/board/linux/libiosyscalls/src/syscalls_stdio.cpp @@ -378,7 +378,7 @@ extern "C" if(vfs::is_filex(__stream)) { TRACE_SYSCALLN("(%p) -> VFS", __stream); - ret = vfs::get_native_fd(reinterpret_cast(__stream)); + ret = vfs::to_native_fd(reinterpret_cast(__stream)->fd); } else { diff --git a/board/linux/libiosyscalls/test/CMakeLists.txt b/board/linux/libiosyscalls/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..412469a71cc87f96cae957fb64dcedf72458aff2 --- /dev/null +++ b/board/linux/libiosyscalls/test/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.12) + +# iosyscalls tests +add_catch2_executable( + NAME + iosyscalls + SRCS + ${CMAKE_CURRENT_LIST_DIR}/unittest_iosys.cpp + LIBS + module-vfs iosyscalls + DEPS + PurePhone.img-target +) diff --git a/board/linux/libiosyscalls/test/unittest_iosys.cpp b/board/linux/libiosyscalls/test/unittest_iosys.cpp new file mode 100644 index 0000000000000000000000000000000000000000..38c7f39200194ac9fcd674bb0e4becc590db321a --- /dev/null +++ b/board/linux/libiosyscalls/test/unittest_iosys.cpp @@ -0,0 +1,36 @@ +// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#define CATCH_CONFIG_MAIN + +#include +#include + +#include + +TEST_CASE("VFS linux support") +{ + auto vfs = purefs::subsystem::initialize(); + auto err = purefs::subsystem::mount_defaults(); + REQUIRE(err == 0); + + static constexpr auto filenm = "assets/lang/English.json"; + + SECTION("std::filesystem") { + REQUIRE(std::filesystem::file_size(filenm) > 0); + } + + SECTION("iterators") { + std::ifstream myfile(filenm); + REQUIRE (myfile.is_open()); + + auto __first = std::istreambuf_iterator(myfile); + auto __last = std::istreambuf_iterator(); + std::vector testvec(__first, __last); + + testvec.push_back('\0'); + REQUIRE(std::string(testvec.data()).length() > 0); + } + + REQUIRE(purefs::subsystem::unmount_all() == 0); +} diff --git a/board/linux/libiosyscalls/version.txt b/board/linux/libiosyscalls/version.txt index cd4ab0810fa58ad1d9db17b13c5e2c0e6b5ab4c7..c95dd19ecdd248cc970109fd9f9b722c7bc48f19 100644 --- a/board/linux/libiosyscalls/version.txt +++ b/board/linux/libiosyscalls/version.txt @@ -62,6 +62,7 @@ GLIBC_2.2.5 { __xstat64; __lxstat64; __fxstat64; + read; mount; umount; # posix - dirent @@ -73,7 +74,6 @@ GLIBC_2.2.5 { seekdir; telldir; # posix - not implemented -# read; # write; # lseek; # lseek64;