Skip to content

Commit

Permalink
Kernel: Make O_RDONLY non-zero
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
awesomekling committed Jan 21, 2020
1 parent efbd162 commit 6081c76
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 33 deletions.
12 changes: 2 additions & 10 deletions Kernel/FileSystem/FileDescription.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,8 @@ class FileDescription : public RefCounted<FileDescription> {

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();
Expand Down
27 changes: 13 additions & 14 deletions Kernel/FileSystem/VirtualFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions Kernel/FileSystem/VirtualFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Kernel/Net/LocalSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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__NOERROR, mode, current->process().current_directory(), owner);
auto result = VFS::the().open(path, O_CREAT | O_EXCL | O__NOERROR, mode, current->process().current_directory(), owner);
if (result.is_error()) {
if (result.error() == -EEXIST)
return KResult(-EADDRINUSE);
Expand Down
4 changes: 2 additions & 2 deletions Kernel/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions Libraries/LibC/fcntl.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ __BEGIN_DECLS

#define FD_CLOEXEC 1

#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_ACCMODE 3
#define O_EXEC 4
#define O_CREAT 0100
Expand Down

0 comments on commit 6081c76

Please sign in to comment.