Kernel: Move file finding code to a helper
This commit is contained in:
parent
a6b973003b
commit
b779b3cf2d
|
@ -213,6 +213,8 @@ namespace Kernel
|
||||||
Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
|
Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
|
||||||
static Process* create_process(const Credentials&, pid_t parent, pid_t sid = 0, pid_t pgrp = 0);
|
static Process* create_process(const Credentials&, pid_t parent, pid_t sid = 0, pid_t pgrp = 0);
|
||||||
|
|
||||||
|
BAN::ErrorOr<VirtualFileSystem::File> find_file(int fd, const char* path, int flags);
|
||||||
|
|
||||||
BAN::ErrorOr<void> validate_string_access(const char*);
|
BAN::ErrorOr<void> validate_string_access(const char*);
|
||||||
BAN::ErrorOr<void> validate_pointer_access_check(const void*, size_t, bool needs_write);
|
BAN::ErrorOr<void> validate_pointer_access_check(const void*, size_t, bool needs_write);
|
||||||
BAN::ErrorOr<void> validate_pointer_access(const void*, size_t, bool needs_write);
|
BAN::ErrorOr<void> validate_pointer_access(const void*, size_t, bool needs_write);
|
||||||
|
|
|
@ -351,6 +351,28 @@ namespace Kernel
|
||||||
return read_from_vec_of_str(m_environ, offset, buffer);
|
return read_from_vec_of_str(m_environ, offset, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<VirtualFileSystem::File> Process::find_file(int fd, const char* path, int flags)
|
||||||
|
{
|
||||||
|
ASSERT(m_process_lock.is_locked());
|
||||||
|
|
||||||
|
if (path)
|
||||||
|
TRY(validate_string_access(path));
|
||||||
|
|
||||||
|
VirtualFileSystem::File parent_file;
|
||||||
|
if (path && path[0] == '/')
|
||||||
|
parent_file = VirtualFileSystem::get().root_file();
|
||||||
|
else if (fd == AT_FDCWD)
|
||||||
|
parent_file = TRY(m_working_directory.clone());
|
||||||
|
else
|
||||||
|
parent_file = TRY(m_open_file_descriptors.file_of(fd));
|
||||||
|
|
||||||
|
auto file = path
|
||||||
|
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags))
|
||||||
|
: BAN::move(parent_file);
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_exit(int status)
|
BAN::ErrorOr<long> Process::sys_exit(int status)
|
||||||
{
|
{
|
||||||
ASSERT(this == &Process::current());
|
ASSERT(this == &Process::current());
|
||||||
|
@ -1000,15 +1022,7 @@ namespace Kernel
|
||||||
TRY(validate_string_access(path));
|
TRY(validate_string_access(path));
|
||||||
TRY(validate_pointer_access(buffer, bufsize, true));
|
TRY(validate_pointer_access(buffer, bufsize, true));
|
||||||
|
|
||||||
VirtualFileSystem::File parent_file;
|
auto inode = TRY(find_file(fd, path, O_NOFOLLOW | O_RDONLY)).inode;
|
||||||
if (path[0] == '/')
|
|
||||||
parent_file = VirtualFileSystem::get().root_file();
|
|
||||||
else if (fd == AT_FDCWD)
|
|
||||||
parent_file = TRY(m_working_directory.clone());
|
|
||||||
else
|
|
||||||
parent_file = TRY(m_open_file_descriptors.file_of(fd));
|
|
||||||
|
|
||||||
auto inode = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, O_NOFOLLOW | O_RDONLY)).inode;
|
|
||||||
|
|
||||||
// FIXME: no allocation needed
|
// FIXME: no allocation needed
|
||||||
auto link_target = TRY(inode->link_target());
|
auto link_target = TRY(inode->link_target());
|
||||||
|
@ -1036,20 +1050,8 @@ namespace Kernel
|
||||||
flag = O_NOFOLLOW;
|
flag = O_NOFOLLOW;
|
||||||
|
|
||||||
LockGuard _(m_process_lock);
|
LockGuard _(m_process_lock);
|
||||||
if (path)
|
|
||||||
TRY(validate_string_access(path));
|
|
||||||
|
|
||||||
VirtualFileSystem::File parent_file;
|
auto inode = TRY(find_file(fd, path, O_SEARCH | flag)).inode;
|
||||||
if (path && path[0] == '/')
|
|
||||||
parent_file = VirtualFileSystem::get().root_file();
|
|
||||||
else if (fd == AT_FDCWD)
|
|
||||||
parent_file = TRY(m_working_directory.clone());
|
|
||||||
else
|
|
||||||
parent_file = TRY(m_open_file_descriptors.file_of(fd));
|
|
||||||
|
|
||||||
auto inode = path
|
|
||||||
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flag)).inode
|
|
||||||
: parent_file.inode;
|
|
||||||
|
|
||||||
if (!m_credentials.is_superuser() && inode->uid() != m_credentials.euid())
|
if (!m_credentials.is_superuser() && inode->uid() != m_credentials.euid())
|
||||||
{
|
{
|
||||||
|
@ -1070,20 +1072,8 @@ namespace Kernel
|
||||||
flag = O_NOFOLLOW;
|
flag = O_NOFOLLOW;
|
||||||
|
|
||||||
LockGuard _(m_process_lock);
|
LockGuard _(m_process_lock);
|
||||||
if (path)
|
|
||||||
TRY(validate_string_access(path));
|
|
||||||
|
|
||||||
VirtualFileSystem::File parent_file;
|
auto inode = TRY(find_file(fd, path, O_SEARCH | flag)).inode;
|
||||||
if (path && path[0] == '/')
|
|
||||||
parent_file = VirtualFileSystem::get().root_file();
|
|
||||||
else if (fd == AT_FDCWD)
|
|
||||||
parent_file = TRY(m_working_directory.clone());
|
|
||||||
else
|
|
||||||
parent_file = TRY(m_open_file_descriptors.file_of(fd));
|
|
||||||
|
|
||||||
auto inode = path
|
|
||||||
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flag)).inode
|
|
||||||
: parent_file.inode;
|
|
||||||
|
|
||||||
if (uid != -1 && !m_credentials.is_superuser())
|
if (uid != -1 && !m_credentials.is_superuser())
|
||||||
return BAN::Error::from_errno(EPERM);
|
return BAN::Error::from_errno(EPERM);
|
||||||
|
@ -1425,29 +1415,17 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_fstatat(int fd, const char* path, struct stat* buf, int flags)
|
BAN::ErrorOr<long> Process::sys_fstatat(int fd, const char* path, struct stat* buf, int flag)
|
||||||
{
|
{
|
||||||
if (flags & ~AT_SYMLINK_NOFOLLOW)
|
if (flag & ~AT_SYMLINK_NOFOLLOW)
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
if (flags == AT_SYMLINK_NOFOLLOW)
|
if (flag == AT_SYMLINK_NOFOLLOW)
|
||||||
flags = O_NOFOLLOW;
|
flag = O_NOFOLLOW;
|
||||||
|
|
||||||
LockGuard _(m_process_lock);
|
LockGuard _(m_process_lock);
|
||||||
if (path)
|
|
||||||
TRY(validate_string_access(path));
|
|
||||||
TRY(validate_pointer_access(buf, sizeof(struct stat), true));
|
TRY(validate_pointer_access(buf, sizeof(struct stat), true));
|
||||||
|
|
||||||
VirtualFileSystem::File parent_file;
|
auto inode = TRY(find_file(fd, path, O_SEARCH | flag)).inode;
|
||||||
if (path && path[0] == '/')
|
|
||||||
parent_file = VirtualFileSystem::get().root_file();
|
|
||||||
else if (fd == AT_FDCWD)
|
|
||||||
parent_file = TRY(m_working_directory.clone());
|
|
||||||
else
|
|
||||||
parent_file = TRY(m_open_file_descriptors.file_of(fd));
|
|
||||||
|
|
||||||
const auto inode = path
|
|
||||||
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags)).inode
|
|
||||||
: parent_file.inode;
|
|
||||||
buf->st_dev = inode->dev();
|
buf->st_dev = inode->dev();
|
||||||
buf->st_ino = inode->ino();
|
buf->st_ino = inode->ino();
|
||||||
buf->st_mode = inode->mode().mode;
|
buf->st_mode = inode->mode().mode;
|
||||||
|
|
Loading…
Reference in New Issue