Kernel: Add basic Credentials for the system
Now filesystem access/open, etc confirm that you have access for rwxs
This commit is contained in:
59
kernel/kernel/FS/Inode.cpp
Normal file
59
kernel/kernel/FS/Inode.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include <kernel/FS/Inode.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
bool Inode::can_access(const Credentials& credentials, int flags)
|
||||
{
|
||||
if (credentials.euid() == 0)
|
||||
return true;
|
||||
|
||||
// We treat O_SEARCH as O_RDONLY
|
||||
if (flags & (O_RDONLY | O_SEARCH))
|
||||
{
|
||||
if (mode().mode & S_IROTH)
|
||||
{ }
|
||||
else if ((mode().mode & S_IRUSR) && credentials.euid() == uid())
|
||||
{ }
|
||||
else if ((mode().mode & S_IRGRP) && credentials.egid() == gid())
|
||||
{ }
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & O_WRONLY)
|
||||
{
|
||||
if (mode().mode & S_IWOTH)
|
||||
{ }
|
||||
else if ((mode().mode & S_IWUSR) && credentials.euid() == uid())
|
||||
{ }
|
||||
else if ((mode().mode & S_IWGRP) && credentials.egid() == gid())
|
||||
{ }
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & O_EXEC)
|
||||
{
|
||||
if (mode().mode & S_IXOTH)
|
||||
{ }
|
||||
else if ((mode().mode & S_IXUSR) && credentials.euid() == uid())
|
||||
{ }
|
||||
else if ((mode().mode & S_IXGRP) && credentials.egid() == gid())
|
||||
{ }
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,32 +4,27 @@
|
||||
#include <kernel/FS/Ext2.h>
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
#include <kernel/LockGuard.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
static VirtualFileSystem* s_instance = nullptr;
|
||||
|
||||
BAN::ErrorOr<void> VirtualFileSystem::initialize(BAN::StringView root)
|
||||
void VirtualFileSystem::initialize(BAN::StringView root)
|
||||
{
|
||||
ASSERT(s_instance == nullptr);
|
||||
s_instance = new VirtualFileSystem();
|
||||
if (s_instance == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
BAN::ScopeGuard guard([] { delete s_instance; s_instance = nullptr; } );
|
||||
ASSERT(s_instance);
|
||||
|
||||
ASSERT(root.size() >= 5 && root.substring(0, 5) == "/dev/"sv);;
|
||||
root = root.substring(5);
|
||||
|
||||
auto partition_inode = TRY(DeviceManager::get().read_directory_inode(root));
|
||||
s_instance->m_root_fs = TRY(Ext2FS::create(*(Partition*)partition_inode.ptr()));
|
||||
auto partition_inode = MUST(DeviceManager::get().read_directory_inode(root));
|
||||
s_instance->m_root_fs = MUST(Ext2FS::create(*(Partition*)partition_inode.ptr()));
|
||||
|
||||
DeviceManager::get().set_blksize(s_instance->m_root_fs->root_inode()->blksize());
|
||||
TRY(s_instance->mount(&DeviceManager::get(), "/dev"));
|
||||
|
||||
guard.disable();
|
||||
|
||||
return {};
|
||||
MUST(s_instance->mount({ 0, 0, 0, 0 }, &DeviceManager::get(), "/dev"));
|
||||
}
|
||||
|
||||
VirtualFileSystem& VirtualFileSystem::get()
|
||||
@@ -38,9 +33,9 @@ namespace Kernel
|
||||
return *s_instance;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> VirtualFileSystem::mount(BAN::StringView partition, BAN::StringView target)
|
||||
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::StringView partition, BAN::StringView target)
|
||||
{
|
||||
auto partition_file = TRY(file_from_absolute_path(partition, true));
|
||||
auto partition_file = TRY(file_from_absolute_path(credentials, partition, true));
|
||||
if (!partition_file.inode->is_device())
|
||||
return BAN::Error::from_errno(ENOTBLK);
|
||||
|
||||
@@ -49,12 +44,12 @@ namespace Kernel
|
||||
return BAN::Error::from_errno(ENOTBLK);
|
||||
|
||||
auto* file_system = TRY(Ext2FS::create(*(Partition*)device));
|
||||
return mount(file_system, target);
|
||||
return mount(credentials, file_system, target);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> VirtualFileSystem::mount(FileSystem* file_system, BAN::StringView path)
|
||||
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, FileSystem* file_system, BAN::StringView path)
|
||||
{
|
||||
auto file = TRY(file_from_absolute_path(path, true));
|
||||
auto file = TRY(file_from_absolute_path(credentials, path, true));
|
||||
if (!file.inode->mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
|
||||
@@ -82,7 +77,7 @@ namespace Kernel
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_absolute_path(BAN::StringView path, bool follow_link)
|
||||
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_absolute_path(const Credentials& credentials, BAN::StringView path, int flags)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
@@ -129,6 +124,9 @@ namespace Kernel
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!inode->can_access(credentials, O_RDONLY))
|
||||
return BAN::Error::from_errno(EACCES);
|
||||
|
||||
inode = TRY(inode->read_directory_inode(path_part));
|
||||
|
||||
if (auto* mount_point = mount_from_host_inode(inode))
|
||||
@@ -140,7 +138,7 @@ namespace Kernel
|
||||
|
||||
path_parts.pop_back();
|
||||
|
||||
if (inode->mode().iflnk() && (follow_link || !path_parts.empty()))
|
||||
if (inode->mode().iflnk() && (!(flags & O_NOFOLLOW) || !path_parts.empty()))
|
||||
{
|
||||
auto target = TRY(inode->link_target());
|
||||
if (target.empty())
|
||||
@@ -174,6 +172,9 @@ namespace Kernel
|
||||
}
|
||||
}
|
||||
|
||||
if (!inode->can_access(credentials, flags))
|
||||
return BAN::Error::from_errno(EACCES);
|
||||
|
||||
if (canonical_path.empty())
|
||||
TRY(canonical_path.push_back('/'));
|
||||
|
||||
|
||||
@@ -18,10 +18,10 @@ namespace Kernel
|
||||
static BAN::Vector<Process*> s_processes;
|
||||
static SpinLock s_process_lock;
|
||||
|
||||
Process* Process::create_process()
|
||||
Process* Process::create_process(const Credentials& credentials)
|
||||
{
|
||||
static pid_t s_next_pid = 1;
|
||||
auto* process = new Process(s_next_pid++);
|
||||
auto* process = new Process(credentials, s_next_pid++);
|
||||
ASSERT(process);
|
||||
return process;
|
||||
}
|
||||
@@ -37,7 +37,7 @@ namespace Kernel
|
||||
|
||||
Process* Process::create_kernel(entry_t entry, void* data)
|
||||
{
|
||||
auto* process = create_process();
|
||||
auto* process = create_process({ 0, 0, 0, 0 });
|
||||
MUST(process->m_working_directory.push_back('/'));
|
||||
auto* thread = MUST(Thread::create_kernel(entry, data, process));
|
||||
process->add_thread(thread);
|
||||
@@ -45,11 +45,11 @@ namespace Kernel
|
||||
return process;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<Process*> Process::create_userspace(BAN::StringView path)
|
||||
BAN::ErrorOr<Process*> Process::create_userspace(const Credentials& credentials, BAN::StringView path)
|
||||
{
|
||||
auto elf = TRY(load_elf_for_exec(path, "/"sv, {}));
|
||||
auto elf = TRY(load_elf_for_exec(credentials, path, "/"sv, {}));
|
||||
|
||||
auto* process = create_process();
|
||||
auto* process = create_process(credentials);
|
||||
MUST(process->m_working_directory.push_back('/'));
|
||||
process->m_page_table = BAN::UniqPtr<PageTable>::adopt(MUST(PageTable::create_userspace()));;
|
||||
|
||||
@@ -89,8 +89,9 @@ namespace Kernel
|
||||
return process;
|
||||
}
|
||||
|
||||
Process::Process(pid_t pid)
|
||||
: m_pid(pid)
|
||||
Process::Process(const Credentials& credentials, pid_t pid)
|
||||
: m_credentials(credentials)
|
||||
, m_pid(pid)
|
||||
, m_tty(TTY::current())
|
||||
{ }
|
||||
|
||||
@@ -167,7 +168,7 @@ namespace Kernel
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::UniqPtr<LibELF::ELF>> Process::load_elf_for_exec(BAN::StringView file_path, const BAN::String& cwd, const BAN::Vector<BAN::StringView>& path_env)
|
||||
BAN::ErrorOr<BAN::UniqPtr<LibELF::ELF>> Process::load_elf_for_exec(const Credentials& credentials, BAN::StringView file_path, const BAN::String& cwd, const BAN::Vector<BAN::StringView>& path_env)
|
||||
{
|
||||
if (file_path.empty())
|
||||
return BAN::Error::from_errno(ENOENT);
|
||||
@@ -204,7 +205,7 @@ namespace Kernel
|
||||
TRY(absolute_path.push_back('/'));
|
||||
TRY(absolute_path.append(file_path));
|
||||
|
||||
if (!VirtualFileSystem::get().file_from_absolute_path(absolute_path, true).is_error())
|
||||
if (!VirtualFileSystem::get().file_from_absolute_path(credentials, absolute_path, O_EXEC).is_error())
|
||||
break;
|
||||
|
||||
absolute_path.clear();
|
||||
@@ -214,7 +215,9 @@ namespace Kernel
|
||||
return BAN::Error::from_errno(ENOENT);
|
||||
}
|
||||
|
||||
auto elf_or_error = LibELF::ELF::load_from_file(absolute_path);
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(credentials, absolute_path, O_EXEC));
|
||||
|
||||
auto elf_or_error = LibELF::ELF::load_from_file(file.inode);
|
||||
if (elf_or_error.is_error())
|
||||
{
|
||||
if (elf_or_error.error().get_error_code() == EINVAL)
|
||||
@@ -240,7 +243,7 @@ namespace Kernel
|
||||
|
||||
BAN::ErrorOr<Process*> Process::fork(uintptr_t rsp, uintptr_t rip)
|
||||
{
|
||||
Process* forked = create_process();
|
||||
Process* forked = create_process(m_credentials);
|
||||
|
||||
forked->m_page_table = BAN::UniqPtr<PageTable>::adopt(MUST(PageTable::create_userspace()));
|
||||
|
||||
@@ -286,7 +289,7 @@ namespace Kernel
|
||||
path_env = TRY(BAN::StringView(envp[i]).substring(5).split(':'));
|
||||
}
|
||||
|
||||
auto elf = TRY(load_elf_for_exec(path, TRY(working_directory()), path_env));
|
||||
auto elf = TRY(load_elf_for_exec(m_credentials, path, TRY(working_directory()), path_env));
|
||||
|
||||
LockGuard lock_guard(m_lock);
|
||||
|
||||
@@ -456,7 +459,7 @@ namespace Kernel
|
||||
|
||||
BAN::String absolute_path = TRY(absolute_path_of(path));
|
||||
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(absolute_path, !(flags & O_NOFOLLOW)));
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags));
|
||||
|
||||
LockGuard _(m_lock);
|
||||
int fd = TRY(get_free_fd());
|
||||
@@ -592,7 +595,7 @@ namespace Kernel
|
||||
auto directory = absolute_path.sv().substring(0, index);
|
||||
auto file_name = absolute_path.sv().substring(index);
|
||||
|
||||
auto parent_file = TRY(VirtualFileSystem::get().file_from_absolute_path(directory, true));
|
||||
auto parent_file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, directory, O_WRONLY));
|
||||
TRY(parent_file.inode->create_file(file_name, mode));
|
||||
|
||||
return {};
|
||||
@@ -606,7 +609,7 @@ namespace Kernel
|
||||
absolute_source = TRY(absolute_path_of(source));
|
||||
absolute_target = TRY(absolute_path_of(target));
|
||||
}
|
||||
TRY(VirtualFileSystem::get().mount(absolute_source, absolute_target));
|
||||
TRY(VirtualFileSystem::get().mount(m_credentials, absolute_source, absolute_target));
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -680,7 +683,7 @@ namespace Kernel
|
||||
{
|
||||
BAN::String absolute_path = TRY(absolute_path_of(path));
|
||||
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(absolute_path, true));
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_SEARCH));
|
||||
if (!file.inode->mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
|
||||
|
||||
@@ -173,14 +173,14 @@ static void init2(void* tty1)
|
||||
DeviceManager::get().initialize_pci_devices();
|
||||
DeviceManager::get().initialize_updater();
|
||||
|
||||
MUST(VirtualFileSystem::initialize(cmdline.root));
|
||||
VirtualFileSystem::initialize(cmdline.root);
|
||||
|
||||
if (auto res = PS2Controller::initialize(); res.is_error())
|
||||
dprintln("{}", res.error());
|
||||
|
||||
((TTY*)tty1)->initialize_device();
|
||||
|
||||
MUST(Process::create_userspace("/usr/bin/Shell"sv));
|
||||
MUST(Process::create_userspace({ 0, 0, 0, 0 }, "/usr/bin/Shell"sv));
|
||||
return;
|
||||
|
||||
Process::create_kernel(
|
||||
|
||||
Reference in New Issue
Block a user