diff options
author | Andreas Kling <kling@serenityos.org> | 2020-01-21 13:14:26 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-01-21 13:27:08 +0100 |
commit | 6081c7651582065c36d5316ae526140b2a4adc46 (patch) | |
tree | ccd294776b578004a339dac44ed2ac8310b87de3 /Kernel | |
parent | efbd1620d9b3b74243b11fc3d6d9cab6b9f93174 (diff) | |
download | serenity-6081c7651582065c36d5316ae526140b2a4adc46.zip |
Kernel: Make O_RDONLY non-zero
Sergey suggested that having a non-zero O_RDONLY would make some things
less confusing, and it seems like he's right about that.
We can now easily check read/write permissions separately instead of
dancing around with the bits.
This patch also fixes unveil() validation for O_RDWR which previously
forgot to check for "r" permission.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/FileSystem/FileDescription.h | 12 | ||||
-rw-r--r-- | Kernel/FileSystem/VirtualFileSystem.cpp | 27 | ||||
-rw-r--r-- | Kernel/FileSystem/VirtualFileSystem.h | 6 | ||||
-rw-r--r-- | Kernel/Net/LocalSocket.cpp | 2 | ||||
-rw-r--r-- | Kernel/Process.cpp | 4 |
5 files changed, 21 insertions, 30 deletions
diff --git a/Kernel/FileSystem/FileDescription.h b/Kernel/FileSystem/FileDescription.h index e907545d9b..4638f00028 100644 --- a/Kernel/FileSystem/FileDescription.h +++ b/Kernel/FileSystem/FileDescription.h @@ -59,16 +59,8 @@ public: void set_rw_mode(int options) { - if (options & O_WRONLY) { - set_readable(false); - set_writable(true); - } else if (options & O_RDWR) { - set_readable(true); - set_writable(true); - } else { - set_readable(true); - set_writable(false); - } + set_readable(options & O_RDONLY); + set_writable(options & O_WRONLY); } int close(); diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index d87e70c28b..6b4ba042eb 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -239,13 +239,10 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::open(StringView path, int options bool should_truncate_file = false; - // NOTE: Read permission is a bit weird, since O_RDONLY == 0, - // so we check if (NOT write_only OR read_and_write) - if (!(options & O_WRONLY) || (options & O_RDWR)) { - if (!metadata.may_read(current->process())) - return KResult(-EACCES); - } - if ((options & O_WRONLY) || (options & O_RDWR)) { + if ((options & O_RDONLY) && !metadata.may_read(current->process())) + return KResult(-EACCES); + + if (options & O_WRONLY) { if (!metadata.may_write(current->process())) return KResult(-EACCES); if (metadata.is_directory()) @@ -748,21 +745,23 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options) } return KSuccess; } - if ((options & O_RDWR) || (options & O_WRONLY)) { + if (options & O_RDONLY) { + if (!(unveiled_path->permissions & UnveiledPath::Access::Read)) { + dbg() << *current << " rejecting path '" << path << "' since it hasn't been unveiled with 'r' permission."; + return KResult(-EACCES); + } + } + if (options & O_WRONLY) { if (!(unveiled_path->permissions & UnveiledPath::Access::Write)) { dbg() << *current << " rejecting path '" << path << "' since it hasn't been unveiled with 'w' permission."; return KResult(-EACCES); } - } else if (options & O_EXEC) { + } + if (options & O_EXEC) { if (!(unveiled_path->permissions & UnveiledPath::Access::Execute)) { dbg() << *current << " rejecting path '" << path << "' since it hasn't been unveiled with 'x' permission."; return KResult(-EACCES); } - } else { - if (!(unveiled_path->permissions & UnveiledPath::Access::Read)) { - dbg() << *current << " rejecting path '" << path << "' since it hasn't been unveiled with 'r' permission."; - return KResult(-EACCES); - } } return KSuccess; } diff --git a/Kernel/FileSystem/VirtualFileSystem.h b/Kernel/FileSystem/VirtualFileSystem.h index 27fcc172dc..3984f9eb3a 100644 --- a/Kernel/FileSystem/VirtualFileSystem.h +++ b/Kernel/FileSystem/VirtualFileSystem.h @@ -38,9 +38,9 @@ #include <Kernel/FileSystem/InodeMetadata.h> #include <Kernel/KResult.h> -#define O_RDONLY 0 -#define O_WRONLY 1 -#define O_RDWR 2 +#define O_RDONLY 1 +#define O_WRONLY 2 +#define O_RDWR 3 #define O_EXEC 4 #define O_CREAT 0100 #define O_EXCL 0200 diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index 12269b83fa..0c59ba14f8 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -111,7 +111,7 @@ KResult LocalSocket::bind(const sockaddr* user_address, socklen_t address_size) mode_t mode = S_IFSOCK | (m_prebind_mode & 04777); UidAndGid owner { m_prebind_uid, m_prebind_gid }; - auto result = VFS::the().open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW_NOERROR, mode, current->process().current_directory(), owner); + auto result = VFS::the().open(path, O_CREAT | O_EXCL | O_NOFOLLOW_NOERROR, mode, current->process().current_directory(), owner); if (result.is_error()) { if (result.error() == -EEXIST) return KResult(-EADDRINUSE); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 6be807edaa..56dc3ea059 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1945,9 +1945,9 @@ int Process::sys$open(const Syscall::SC_open_params* user_params) if (options & O_UNLINK_INTERNAL) return -EINVAL; - if ((options & O_RDWR) || (options & O_WRONLY)) + if (options & O_WRONLY) REQUIRE_PROMISE(wpath); - else + else if (options & O_RDONLY) REQUIRE_PROMISE(rpath); if (options & O_CREAT) |