From b810f7f88af5346e0ec12b9fdecb855b34ebba66 Mon Sep 17 00:00:00 2001 From: Karol Kosek Date: Wed, 31 Aug 2022 22:07:16 +0200 Subject: [PATCH] LibCore: Implement File::can_delete_or_move() Besides from a general check if a file's directory has write permissions, this also checks if the directory has set a sticky bit, meaning that only file owners and the directory owner can remove or move files in such directory. It's being used in /tmp for example. --- Userland/Libraries/LibCore/File.cpp | 27 +++++++++++++++++++++++++++ Userland/Libraries/LibCore/File.h | 1 + 2 files changed, 28 insertions(+) diff --git a/Userland/Libraries/LibCore/File.cpp b/Userland/Libraries/LibCore/File.cpp index ace8386cd0..fb235eb3db 100644 --- a/Userland/Libraries/LibCore/File.cpp +++ b/Userland/Libraries/LibCore/File.cpp @@ -202,6 +202,33 @@ bool File::looks_like_shared_library(DeprecatedString const& filename) return filename.ends_with(".so"sv) || filename.contains(".so."sv); } +bool File::can_delete_or_move(StringView path) +{ + VERIFY(!path.is_empty()); + auto directory = LexicalPath::dirname(path); + auto directory_has_write_access = !Core::System::access(directory, W_OK).is_error(); + if (!directory_has_write_access) + return false; + + auto stat_or_empty = [](StringView path) { + auto stat_or_error = Core::System::stat(path); + if (stat_or_error.is_error()) { + struct stat stat { }; + return stat; + } + return stat_or_error.release_value(); + }; + + auto directory_stat = stat_or_empty(directory); + bool is_directory_sticky = directory_stat.st_mode & S_ISVTX; + if (!is_directory_sticky) + return true; + + // Directory is sticky, only the file owner, directory owner, and root can modify (rename, remove) it. + auto user_id = geteuid(); + return user_id == 0 || directory_stat.st_uid == user_id || stat_or_empty(path).st_uid == user_id; +} + bool File::exists(StringView filename) { return !Core::System::stat(filename).is_error(); diff --git a/Userland/Libraries/LibCore/File.h b/Userland/Libraries/LibCore/File.h index 36022cfabf..4dbeaa1414 100644 --- a/Userland/Libraries/LibCore/File.h +++ b/Userland/Libraries/LibCore/File.h @@ -53,6 +53,7 @@ public: static ErrorOr size(DeprecatedString const& filename); static DeprecatedString current_working_directory(); static DeprecatedString absolute_path(DeprecatedString const& path); + static bool can_delete_or_move(StringView path); enum class RecursionMode { Allowed,