From 488c746ac12a2fb35417bfd31f5bce1707df9672 Mon Sep 17 00:00:00 2001 From: "Maxim [maxirmx] Samsonov" Date: Tue, 1 Aug 2023 22:49:59 +0300 Subject: [PATCH] Fixed access function (https://github.com/tamatebako/tebako/issues/62) --- .github/workflows/lint.yml | 16 ++++++++-------- src/tebako-dfs.cpp | 28 ++++++++++++++++++++++++++-- src/tebako-fd.cpp | 6 ++---- tests/tests-file-ctl.cpp | 20 +++++++++++++++++++- version.txt | 2 +- 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fca35705..75051d69 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -66,11 +66,11 @@ jobs: source: '.' extensions: 'h,cpp,c' clangFormatVersion: 14 -# inplace: True -# - uses: EndBug/add-and-commit@v9 -# with: -# author_name: A robot on behalf of Maxim Samsonov -# author_email: maxirmx@sw.consulting -# message: 'Committing clang-format changes' -# env: -# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + inplace: True + - uses: EndBug/add-and-commit@v9 + with: + author_name: A robot on behalf of Maxim Samsonov + author_email: maxirmx@sw.consulting + message: 'Committing clang-format changes' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/src/tebako-dfs.cpp b/src/tebako-dfs.cpp index 6601abd7..35aa3cda 100644 --- a/src/tebako-dfs.cpp +++ b/src/tebako-dfs.cpp @@ -271,6 +271,19 @@ int safe_dwarfs_call(Functor&& fn, return ret; } +// We are testing against owner permissions +static int dwarfs_access_inner(int amode, struct stat* st) +{ + int ret = DWARFS_IO_CONTINUE; + if ((!(st->st_mode & S_IRUSR) && (amode & R_OK)) || + (!(st->st_mode & S_IWUSR) && (amode & W_OK)) || + (!(st->st_mode & S_IXUSR) && (amode & X_OK))) { + ret = DWARFS_IO_ERROR; + TEBAKO_SET_LAST_ERROR(EACCES); + } + return ret; +} + int dwarfs_access(const char* path, int amode, uid_t uid, @@ -280,7 +293,7 @@ int dwarfs_access(const char* path, struct stat st; int ret = dwarfs_stat(path, &st, lnk); if (ret == DWARFS_IO_CONTINUE) { - ret = dwarfs_inode_access(st.st_ino, amode, uid, gid); + ret = dwarfs_access_inner(amode, &st); } return ret; } @@ -434,8 +447,19 @@ int dwarfs_inode_access(uint32_t inode, std::function{ [](filesystem_v2* fs, uint32_t inode, int amode, uid_t uid, gid_t gid) -> int { + int ret = DWARFS_IO_ERROR; auto pi = fs->find(inode); - return pi ? fs->access(*pi, amode, uid, gid) : ENOENT; + if (pi) { + struct stat st; + ret = fs->getattr(*pi, &st); + if (ret == DWARFS_IO_CONTINUE) { + ret = dwarfs_access_inner(amode, &st); + } + } + else { + TEBAKO_SET_LAST_ERROR(ENOENT); + } + return ret; }}, __func__, inode, amode, uid, gid); } diff --git a/src/tebako-fd.cpp b/src/tebako-fd.cpp index 202e5898..25150fa4 100644 --- a/src/tebako-fd.cpp +++ b/src/tebako-fd.cpp @@ -191,7 +191,8 @@ int sync_tebako_fdtable::openat(int vfd, const char* path, int flags) noexcept // on a read - only file system and either O_WRONLY, O_RDWR, // O_CREAT(if the file does not exist), or O_TRUNC is set in the // oflag argument. - TEBAKO_SET_LAST_ERROR((flags & O_CREAT) ? EROFS : ENOENT); + if (flags & O_CREAT) + TEBAKO_SET_LAST_ERROR(EROFS); } } catch (bad_alloc&) { @@ -366,9 +367,6 @@ int sync_tebako_fdtable::fstatat(int vfd, if (ret == DWARFS_IO_CONTINUE) { ret = dwarfs_inode_relative_stat(stfd.st_ino, path, st, follow); } - else { - TEBAKO_SET_LAST_ERROR(ENOENT); - } } } return ret; diff --git a/tests/tests-file-ctl.cpp b/tests/tests-file-ctl.cpp index dd237d50..2508588e 100644 --- a/tests/tests-file-ctl.cpp +++ b/tests/tests-file-ctl.cpp @@ -55,11 +55,21 @@ TEST_F(FileCtlTests, tebako_access_absolute_path) { int ret = tebako_access(TEBAKIZE_PATH("file.txt"), F_OK); EXPECT_EQ(0, ret); + ret = tebako_access(TEBAKIZE_PATH("file.txt"), R_OK); + EXPECT_EQ(0, ret); + ret = tebako_access(TEBAKIZE_PATH("file.txt"), W_OK); + EXPECT_EQ(0, ret); + ret = tebako_access(TEBAKIZE_PATH("file.txt"), X_OK); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EACCES, errno); } TEST_F(FileCtlTests, tebako_access_absolute_path_no_file) { - int ret = tebako_access(TEBAKIZE_PATH("no-directory/file.txt"), W_OK); + int ret = tebako_access(TEBAKIZE_PATH("no-directory/file.txt"), X_OK); + EXPECT_EQ(ENOENT, errno); + EXPECT_EQ(-1, ret); + ret = tebako_access(TEBAKIZE_PATH("no-file.txt"), F_OK); EXPECT_EQ(ENOENT, errno); EXPECT_EQ(-1, ret); } @@ -75,8 +85,16 @@ TEST_F(FileCtlTests, tebako_access_relative_path) { int ret = tebako_chdir(TEBAKIZE_PATH("directory-2")); EXPECT_EQ(0, ret); + ret = tebako_access("file-in-directory-2.txt", F_OK); + EXPECT_EQ(0, ret); ret = tebako_access("file-in-directory-2.txt", R_OK); EXPECT_EQ(0, ret); + ret = tebako_access("file-in-directory-2.txt", W_OK); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EACCES, errno); + ret = tebako_access("file-in-directory-2.txt", X_OK); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EACCES, errno); } TEST_F(FileCtlTests, tebako_access_relative_path_no_file) diff --git a/version.txt b/version.txt index 42045aca..c2c0004f 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.3.4 +0.3.5