Kernel/LibC: Implement chroot
This commit is contained in:
parent
695262624d
commit
309ec660b6
|
@ -20,6 +20,6 @@ namespace Kernel::ELF
|
|||
BAN::Vector<BAN::UniqPtr<MemoryRegion>> regions;
|
||||
};
|
||||
|
||||
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode>, const Credentials&, PageTable&);
|
||||
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> root, BAN::RefPtr<Inode> inode, const Credentials&, PageTable&);
|
||||
|
||||
}
|
||||
|
|
|
@ -71,13 +71,13 @@ namespace Kernel
|
|||
|
||||
File root_file()
|
||||
{
|
||||
return File(root_inode(), "/"_sv);
|
||||
return File { root_inode(), "/"_sv };
|
||||
}
|
||||
|
||||
BAN::ErrorOr<File> file_from_relative_path(const File& parent, const Credentials&, BAN::StringView, int);
|
||||
BAN::ErrorOr<File> file_from_absolute_path(const Credentials& credentials, BAN::StringView path, int flags)
|
||||
BAN::ErrorOr<File> file_from_relative_path(BAN::RefPtr<Inode> root_inode, const File& parent, const Credentials&, BAN::StringView, int);
|
||||
BAN::ErrorOr<File> file_from_absolute_path(BAN::RefPtr<Inode> root_inode, const Credentials& credentials, BAN::StringView path, int flags)
|
||||
{
|
||||
return file_from_relative_path(root_file(), credentials, path, flags);
|
||||
return file_from_relative_path(root_inode, File { root_inode, "/"_sv }, credentials, path, flags);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <BAN/WeakPtr.h>
|
||||
#include <kernel/FS/Socket.h>
|
||||
#include <kernel/FS/TmpFS/Inode.h>
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
#include <kernel/Lock/SpinLock.h>
|
||||
|
||||
namespace Kernel
|
||||
|
@ -39,8 +40,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> add_packet(BAN::ConstByteSpan);
|
||||
|
||||
bool is_bound() const { return !m_bound_path.empty(); }
|
||||
bool is_bound_to_unused() const { return m_bound_path == "X"_sv; }
|
||||
bool is_bound() const { return !m_bound_file.canonical_path.empty(); }
|
||||
bool is_bound_to_unused() const { return !m_bound_file.inode; }
|
||||
|
||||
bool is_streaming() const;
|
||||
|
||||
|
@ -63,7 +64,7 @@ namespace Kernel
|
|||
|
||||
private:
|
||||
const Socket::Type m_socket_type;
|
||||
BAN::String m_bound_path;
|
||||
VirtualFileSystem::File m_bound_file;
|
||||
|
||||
BAN::Variant<ConnectionInfo, ConnectionlessInfo> m_info;
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ namespace Kernel
|
|||
BAN::ErrorOr<long> sys_getcwd(char* buffer, size_t size);
|
||||
BAN::ErrorOr<long> sys_chdir(const char* path);
|
||||
BAN::ErrorOr<long> sys_fchdir(int fildes);
|
||||
BAN::ErrorOr<long> sys_chroot(const char* path);
|
||||
|
||||
BAN::ErrorOr<long> sys_setuid(uid_t);
|
||||
BAN::ErrorOr<long> sys_setgid(gid_t);
|
||||
|
@ -234,6 +235,7 @@ namespace Kernel
|
|||
static void update_alarm_queue();
|
||||
|
||||
const VirtualFileSystem::File& working_directory() const { return m_working_directory; }
|
||||
const VirtualFileSystem::File& root_file() const { return m_root_file; }
|
||||
|
||||
private:
|
||||
Process(const Credentials&, pid_t pid, pid_t parent, pid_t sid, pid_t pgrp);
|
||||
|
@ -313,6 +315,7 @@ namespace Kernel
|
|||
mutable Mutex m_process_lock;
|
||||
|
||||
VirtualFileSystem::File m_working_directory;
|
||||
VirtualFileSystem::File m_root_file;
|
||||
|
||||
BAN::Vector<Thread*> m_threads;
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace Kernel::ELF
|
|||
return BAN::move(program_headers);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> inode, const Credentials& credentials, PageTable& page_table)
|
||||
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> root, BAN::RefPtr<Inode> inode, const Credentials& credentials, PageTable& page_table)
|
||||
{
|
||||
auto file_header = TRY(read_and_validate_file_header(inode));
|
||||
auto program_headers = TRY(read_program_headers(inode, file_header));
|
||||
|
@ -143,7 +143,7 @@ namespace Kernel::ELF
|
|||
|
||||
if (!interpreter.empty())
|
||||
{
|
||||
auto interpreter_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(credentials, interpreter, O_EXEC)).inode;
|
||||
auto interpreter_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(root, credentials, interpreter, O_EXEC)).inode;
|
||||
auto interpreter_file_header = TRY(read_and_validate_file_header(interpreter_inode));
|
||||
auto interpreter_program_headers = TRY(read_program_headers(interpreter_inode, interpreter_file_header));
|
||||
|
||||
|
|
|
@ -186,7 +186,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::StringView block_device_path, BAN::StringView target)
|
||||
{
|
||||
auto block_device_file = TRY(file_from_absolute_path(credentials, block_device_path, true));
|
||||
// TODO: allow custom root
|
||||
auto block_device_file = TRY(file_from_absolute_path(root_inode(), credentials, block_device_path, true));
|
||||
if (!block_device_file.inode->is_device())
|
||||
return BAN::Error::from_errno(ENOTBLK);
|
||||
|
||||
|
@ -200,7 +201,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::RefPtr<FileSystem> file_system, BAN::StringView path)
|
||||
{
|
||||
auto file = TRY(file_from_absolute_path(credentials, path, true));
|
||||
// TODO: allow custom root
|
||||
auto file = TRY(file_from_absolute_path(root_inode(), credentials, path, true));
|
||||
if (!file.inode->mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
|
||||
|
@ -227,7 +229,7 @@ namespace Kernel
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_relative_path(const File& parent, const Credentials& credentials, BAN::StringView path, int flags)
|
||||
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_relative_path(BAN::RefPtr<Inode> root_inode, const File& parent, const Credentials& credentials, BAN::StringView path, int flags)
|
||||
{
|
||||
LockGuard _(m_mutex);
|
||||
|
||||
|
@ -269,6 +271,8 @@ namespace Kernel
|
|||
auto orig = inode;
|
||||
|
||||
// resolve file name
|
||||
{
|
||||
if (!(inode == root_inode && path_part == ".."_sv))
|
||||
{
|
||||
auto parent_inode = inode;
|
||||
if (path_part == ".."_sv)
|
||||
|
@ -277,6 +281,7 @@ namespace Kernel
|
|||
if (!parent_inode->can_access(credentials, O_SEARCH))
|
||||
return BAN::Error::from_errno(EACCES);
|
||||
inode = TRY(parent_inode->find_inode(path_part));
|
||||
}
|
||||
|
||||
if (path_part == ".."_sv)
|
||||
{
|
||||
|
@ -310,7 +315,7 @@ namespace Kernel
|
|||
|
||||
if (link_target.front() == '/')
|
||||
{
|
||||
inode = root_inode();
|
||||
inode = root_inode;
|
||||
canonical_path.clear();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -13,7 +13,15 @@
|
|||
namespace Kernel
|
||||
{
|
||||
|
||||
static BAN::HashMap<BAN::String, BAN::WeakPtr<UnixDomainSocket>> s_bound_sockets;
|
||||
struct UnixSocketHash
|
||||
{
|
||||
BAN::hash_t operator()(const BAN::RefPtr<Inode>& socket)
|
||||
{
|
||||
return BAN::hash<const Inode*>{}(socket.ptr());
|
||||
}
|
||||
};
|
||||
|
||||
static BAN::HashMap<BAN::RefPtr<Inode>, BAN::WeakPtr<UnixDomainSocket>, UnixSocketHash> s_bound_sockets;
|
||||
static SpinLock s_bound_socket_lock;
|
||||
|
||||
static constexpr size_t s_packet_buffer_size = 10 * PAGE_SIZE;
|
||||
|
@ -57,9 +65,7 @@ namespace Kernel
|
|||
if (is_bound() && !is_bound_to_unused())
|
||||
{
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
auto it = s_bound_sockets.find(m_bound_path);
|
||||
if (it != s_bound_sockets.end())
|
||||
s_bound_sockets.remove(it);
|
||||
s_bound_sockets.remove(m_bound_file.inode);
|
||||
}
|
||||
if (m_info.has<ConnectionInfo>())
|
||||
{
|
||||
|
@ -117,17 +123,22 @@ namespace Kernel
|
|||
return_inode = reinterpret_cast<UnixDomainSocket*>(return_inode_tmp.ptr());
|
||||
}
|
||||
|
||||
TRY(return_inode->m_bound_path.push_back('X'));
|
||||
TRY(return_inode->m_bound_file.canonical_path.push_back('X'));
|
||||
return_inode->m_info.get<ConnectionInfo>().connection = TRY(pending->get_weak_ptr());
|
||||
pending->m_info.get<ConnectionInfo>().connection = TRY(return_inode->get_weak_ptr());
|
||||
pending->m_info.get<ConnectionInfo>().connection_done = true;
|
||||
|
||||
if (address && address_len && !is_bound_to_unused())
|
||||
{
|
||||
size_t copy_len = BAN::Math::min<size_t>(*address_len, sizeof(sockaddr) + m_bound_path.size() + 1);
|
||||
auto& sockaddr_un = *reinterpret_cast<struct sockaddr_un*>(address);
|
||||
sockaddr_un.sun_family = AF_UNIX;
|
||||
strncpy(sockaddr_un.sun_path, pending->m_bound_path.data(), copy_len);
|
||||
sockaddr_un sa_un {
|
||||
.sun_family = AF_UNIX,
|
||||
.sun_path {},
|
||||
};
|
||||
strcpy(sa_un.sun_path, pending->m_bound_file.canonical_path.data());
|
||||
|
||||
const size_t to_copy = BAN::Math::min<size_t>(*address_len, sizeof(sockaddr_un));
|
||||
memcpy(address, &sa_un, to_copy);
|
||||
*address_len = to_copy;
|
||||
}
|
||||
|
||||
return TRY(Process::current().open_inode(VirtualFileSystem::File(return_inode, "<unix socket>"_sv), O_RDWR | flags));
|
||||
|
@ -141,10 +152,11 @@ namespace Kernel
|
|||
if (sockaddr_un.sun_family != AF_UNIX)
|
||||
return BAN::Error::from_errno(EAFNOSUPPORT);
|
||||
if (!is_bound())
|
||||
TRY(m_bound_path.push_back('X'));
|
||||
TRY(m_bound_file.canonical_path.push_back('X'));
|
||||
|
||||
auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path));
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(
|
||||
Process::current().root_file().inode,
|
||||
Process::current().credentials(),
|
||||
absolute_path,
|
||||
O_RDWR
|
||||
|
@ -154,7 +166,7 @@ namespace Kernel
|
|||
|
||||
{
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
auto it = s_bound_sockets.find(file.canonical_path);
|
||||
auto it = s_bound_sockets.find(file.inode);
|
||||
if (it == s_bound_sockets.end())
|
||||
return BAN::Error::from_errno(ECONNREFUSED);
|
||||
target = it->value.lock();
|
||||
|
@ -236,7 +248,7 @@ namespace Kernel
|
|||
|
||||
// FIXME: This feels sketchy
|
||||
auto parent_file = bind_path.front() == '/'
|
||||
? VirtualFileSystem::get().root_file()
|
||||
? TRY(Process::current().root_file().clone())
|
||||
: TRY(Process::current().working_directory().clone());
|
||||
if (auto ret = Process::current().create_file_or_dir(AT_FDCWD, bind_path.data(), 0755 | S_IFSOCK); ret.is_error())
|
||||
{
|
||||
|
@ -245,6 +257,7 @@ namespace Kernel
|
|||
return ret.release_error();
|
||||
}
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_relative_path(
|
||||
Process::current().root_file().inode,
|
||||
parent_file,
|
||||
Process::current().credentials(),
|
||||
bind_path,
|
||||
|
@ -252,10 +265,10 @@ namespace Kernel
|
|||
));
|
||||
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
if (s_bound_sockets.contains(file.canonical_path))
|
||||
if (s_bound_sockets.contains(file.inode))
|
||||
return BAN::Error::from_errno(EADDRINUSE);
|
||||
TRY(s_bound_sockets.emplace(file.canonical_path, TRY(get_weak_ptr())));
|
||||
m_bound_path = BAN::move(file.canonical_path);
|
||||
TRY(s_bound_sockets.emplace(file.inode, TRY(get_weak_ptr())));
|
||||
m_bound_file = BAN::move(file);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -354,14 +367,21 @@ namespace Kernel
|
|||
}
|
||||
else
|
||||
{
|
||||
BAN::String canonical_path;
|
||||
BAN::RefPtr<Inode> target_inode;
|
||||
|
||||
if (!address)
|
||||
{
|
||||
auto& connectionless_info = m_info.get<ConnectionlessInfo>();
|
||||
if (connectionless_info.peer_address.empty())
|
||||
return BAN::Error::from_errno(EDESTADDRREQ);
|
||||
TRY(canonical_path.append(connectionless_info.peer_address));
|
||||
|
||||
auto absolute_path = TRY(Process::current().absolute_path_of(connectionless_info.peer_address));
|
||||
target_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(
|
||||
Process::current().root_file().inode,
|
||||
Process::current().credentials(),
|
||||
absolute_path,
|
||||
O_RDWR
|
||||
)).inode;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -372,17 +392,16 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(EAFNOSUPPORT);
|
||||
|
||||
auto absolute_path = TRY(Process::current().absolute_path_of(sockaddr_un.sun_path));
|
||||
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(
|
||||
target_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(
|
||||
Process::current().root_file().inode,
|
||||
Process::current().credentials(),
|
||||
absolute_path,
|
||||
O_WRONLY
|
||||
));
|
||||
|
||||
canonical_path = BAN::move(file.canonical_path);
|
||||
)).inode;
|
||||
}
|
||||
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
auto it = s_bound_sockets.find(canonical_path);
|
||||
auto it = s_bound_sockets.find(target_inode);
|
||||
if (it == s_bound_sockets.end())
|
||||
return BAN::Error::from_errno(EDESTADDRREQ);
|
||||
auto target = it->value.lock();
|
||||
|
@ -449,20 +468,11 @@ namespace Kernel
|
|||
if (!connection)
|
||||
return BAN::Error::from_errno(ENOTCONN);
|
||||
|
||||
sockaddr_un sa_un;
|
||||
sa_un.sun_family = AF_UNIX;
|
||||
sa_un.sun_path[0] = 0;
|
||||
|
||||
{
|
||||
SpinLockGuard _(s_bound_socket_lock);
|
||||
for (auto& [path, socket] : s_bound_sockets)
|
||||
{
|
||||
if (socket.lock() != connection)
|
||||
continue;
|
||||
strcpy(sa_un.sun_path, path.data());
|
||||
break;
|
||||
}
|
||||
}
|
||||
sockaddr_un sa_un {
|
||||
.sun_family = AF_UNIX,
|
||||
.sun_path = {},
|
||||
};
|
||||
strcpy(sa_un.sun_path, connection->m_bound_file.canonical_path.data());
|
||||
|
||||
const size_t to_copy = BAN::Math::min<socklen_t>(sizeof(sockaddr_un), *address_len);
|
||||
memcpy(address, &sa_un, to_copy);
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<int> OpenFileDescriptorSet::open(BAN::StringView absolute_path, int flags)
|
||||
{
|
||||
return open(TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags)), flags);
|
||||
return open(TRY(VirtualFileSystem::get().file_from_absolute_path(Process::current().root_file().inode, m_credentials, absolute_path, flags)), flags);
|
||||
}
|
||||
|
||||
struct SocketInfo
|
||||
|
|
|
@ -103,6 +103,8 @@ namespace Kernel
|
|||
auto* process = create_process(credentials, 0);
|
||||
|
||||
process->m_working_directory = VirtualFileSystem::get().root_file();
|
||||
process->m_root_file = VirtualFileSystem::get().root_file();
|
||||
|
||||
process->m_page_table = BAN::UniqPtr<PageTable>::adopt(MUST(PageTable::create_userspace()));
|
||||
|
||||
TRY(process->m_cmdline.emplace_back());
|
||||
|
@ -118,7 +120,7 @@ namespace Kernel
|
|||
auto executable_file = TRY(process->find_file(AT_FDCWD, path.data(), O_EXEC));
|
||||
auto executable_inode = executable_file.inode;
|
||||
|
||||
auto executable = TRY(ELF::load_from_inode(executable_inode, process->m_credentials, process->page_table()));
|
||||
auto executable = TRY(ELF::load_from_inode(process->m_root_file.inode, executable_inode, process->m_credentials, process->page_table()));
|
||||
process->m_mapped_regions = BAN::move(executable.regions);
|
||||
|
||||
if (executable_inode->mode().mode & +Inode::Mode::ISUID)
|
||||
|
@ -456,7 +458,7 @@ namespace Kernel
|
|||
|
||||
auto parent_file = TRY(find_relative_parent(fd, path));
|
||||
auto file = path
|
||||
? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags))
|
||||
? TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent_file, m_credentials, path, flags))
|
||||
: BAN::move(parent_file);
|
||||
|
||||
return file;
|
||||
|
@ -480,7 +482,7 @@ namespace Kernel
|
|||
|
||||
if (auto index = path_sv.rfind('/'); index.has_value())
|
||||
{
|
||||
parent = TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, m_credentials, path_sv.substring(0, index.value()), flags));
|
||||
parent = TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, relative_parent, m_credentials, path_sv.substring(0, index.value()), flags));
|
||||
file_name = path_sv.substring(index.value() + 1);
|
||||
}
|
||||
else
|
||||
|
@ -510,7 +512,7 @@ namespace Kernel
|
|||
ASSERT(m_process_lock.is_locked());
|
||||
|
||||
if (path && path[0] == '/')
|
||||
return VirtualFileSystem::get().root_file();
|
||||
return TRY(m_root_file.clone());
|
||||
|
||||
if (fd == AT_FDCWD)
|
||||
return TRY(m_working_directory.clone());
|
||||
|
@ -582,6 +584,7 @@ namespace Kernel
|
|||
}
|
||||
|
||||
auto working_directory = TRY(m_working_directory.clone());
|
||||
auto root_file = TRY(m_root_file.clone());
|
||||
|
||||
BAN::Vector<BAN::String> cmdline;
|
||||
TRY(cmdline.resize(m_cmdline.size()));
|
||||
|
@ -604,6 +607,7 @@ namespace Kernel
|
|||
Process* forked = create_process(m_credentials, m_pid, m_sid, m_pgrp);
|
||||
forked->m_controlling_terminal = m_controlling_terminal;
|
||||
forked->m_working_directory = BAN::move(working_directory);
|
||||
forked->m_root_file = BAN::move(root_file);
|
||||
forked->m_cmdline = BAN::move(cmdline);
|
||||
forked->m_environ = BAN::move(environ);
|
||||
forked->m_page_table = BAN::move(page_table);
|
||||
|
@ -656,7 +660,7 @@ namespace Kernel
|
|||
auto executable_file = TRY(find_file(AT_FDCWD, path, O_EXEC));
|
||||
auto executable_inode = executable_file.inode;
|
||||
|
||||
auto executable = TRY(ELF::load_from_inode(executable_inode, m_credentials, *new_page_table));
|
||||
auto executable = TRY(ELF::load_from_inode(m_root_file.inode, executable_inode, m_credentials, *new_page_table));
|
||||
auto new_mapped_regions = BAN::move(executable.regions);
|
||||
|
||||
BAN::Vector<LibELF::AuxiliaryVector> auxiliary_vector;
|
||||
|
@ -1044,7 +1048,7 @@ namespace Kernel
|
|||
TRY(validate_string_access(path));
|
||||
|
||||
auto [parent, file_name] = TRY(find_parent_file(fd, path, O_RDONLY));
|
||||
auto file_or_error = VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags);
|
||||
auto file_or_error = VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent, m_credentials, file_name, flags);
|
||||
|
||||
VirtualFileSystem::File file;
|
||||
if (file_or_error.is_error())
|
||||
|
@ -1054,7 +1058,7 @@ namespace Kernel
|
|||
|
||||
// FIXME: There is a race condition between next two lines
|
||||
TRY(parent.inode->create_file(file_name, (mode & 0777) | Inode::Mode::IFREG, m_credentials.euid(), m_credentials.egid()));
|
||||
file = TRY(VirtualFileSystem::get().file_from_relative_path(parent, m_credentials, file_name, flags & ~O_RDWR));
|
||||
file = TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, parent, m_credentials, file_name, flags & ~O_RDWR));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1135,7 +1139,7 @@ namespace Kernel
|
|||
credentials.set_egid(credentials.rgid());
|
||||
|
||||
auto relative_parent = TRY(find_relative_parent(AT_FDCWD, path));
|
||||
TRY(VirtualFileSystem::get().file_from_relative_path(relative_parent, credentials, path, flags));
|
||||
TRY(VirtualFileSystem::get().file_from_relative_path(m_root_file.inode, relative_parent, credentials, path, flags));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1258,6 +1262,7 @@ namespace Kernel
|
|||
flag = O_NOFOLLOW;
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
auto inode = TRY(find_file(fd, path, flag)).inode;
|
||||
|
||||
|
@ -1280,6 +1285,7 @@ namespace Kernel
|
|||
flag = O_NOFOLLOW;
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
auto inode = TRY(find_file(fd, path, flag)).inode;
|
||||
|
||||
|
@ -2095,22 +2101,25 @@ namespace Kernel
|
|||
BAN::ErrorOr<long> Process::sys_chdir(const char* path)
|
||||
{
|
||||
LockGuard _(m_process_lock);
|
||||
|
||||
TRY(validate_string_access(path));
|
||||
|
||||
auto file = TRY(find_file(AT_FDCWD, path, O_SEARCH));
|
||||
m_working_directory = BAN::move(file);
|
||||
|
||||
m_working_directory = TRY(find_file(AT_FDCWD, path, O_SEARCH));
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_fchdir(int fildes)
|
||||
{
|
||||
LockGuard _(m_process_lock);
|
||||
m_working_directory = TRY(m_open_file_descriptors.file_of(fildes));
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto file = TRY(m_open_file_descriptors.file_of(fildes));
|
||||
m_working_directory = BAN::move(file);
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_chroot(const char* path)
|
||||
{
|
||||
LockGuard _(m_process_lock);
|
||||
TRY(validate_string_access(path));
|
||||
if (!m_credentials.is_superuser())
|
||||
return BAN::Error::from_errno(EACCES);
|
||||
m_root_file = TRY(find_file(AT_FDCWD, path, O_SEARCH));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,8 +121,8 @@ namespace Kernel
|
|||
void TTY::keyboard_task(void*)
|
||||
{
|
||||
BAN::RefPtr<Inode> keyboard_inode;
|
||||
if (auto ret = VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/keyboard"_sv, O_RDONLY); !ret.is_error())
|
||||
keyboard_inode = ret.value().inode;
|
||||
if (auto ret = DevFileSystem::get().root_inode()->find_inode("keyboard"_sv); !ret.is_error())
|
||||
keyboard_inode = ret.release_value();
|
||||
else
|
||||
{
|
||||
dprintln("could not open keyboard device: {}", ret.error());
|
||||
|
|
|
@ -113,6 +113,7 @@ __BEGIN_DECLS
|
|||
O(SYS_FUTEX, futex) \
|
||||
O(SYS_GETGROUPS, getgroups) \
|
||||
O(SYS_SETGROUPS, setgroups) \
|
||||
O(SYS_CHROOT, chroot) \
|
||||
|
||||
enum Syscall
|
||||
{
|
||||
|
|
|
@ -596,6 +596,7 @@ int unlinkat(int fd, const char* path, int flag);
|
|||
int usleep(useconds_t usec);
|
||||
ssize_t write(int fildes, const void* buf, size_t nbyte);
|
||||
|
||||
int chroot(const char* path);
|
||||
int getpagesize(void);
|
||||
char* getpass(const char* prompt);
|
||||
|
||||
|
|
|
@ -626,6 +626,10 @@ int getopt(int argc, char* const argv[], const char* optstring)
|
|||
return '?';
|
||||
}
|
||||
|
||||
int chroot(const char* path)
|
||||
return syscall(SYS_CHROOT, path);
|
||||
}
|
||||
|
||||
int getpagesize(void)
|
||||
{
|
||||
return PAGE_SIZE;
|
||||
|
|
|
@ -31,7 +31,8 @@ namespace LibFont
|
|||
|
||||
#if __is_kernel
|
||||
{
|
||||
auto inode = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, O_RDONLY)).inode;
|
||||
// FIXME: This does not account for chroot
|
||||
auto inode = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path(Kernel::VirtualFileSystem::get().root_inode(), { 0, 0, 0, 0 }, path, O_RDONLY)).inode;
|
||||
TRY(file_data.resize(inode->size()));
|
||||
TRY(inode->read(0, BAN::ByteSpan(file_data.span())));
|
||||
}
|
||||
|
|
|
@ -128,7 +128,8 @@ namespace LibInput
|
|||
|
||||
#if __is_kernel
|
||||
{
|
||||
auto file = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, path, 0));
|
||||
// FIXME: This does not account for chroot
|
||||
auto file = TRY(Kernel::VirtualFileSystem::get().file_from_absolute_path(Kernel::VirtualFileSystem::get().root_inode(), { 0, 0, 0, 0 }, path, 0));
|
||||
TRY(file_data.resize(file.inode->size()));
|
||||
TRY(file.inode->read(0, BAN::ByteSpan { reinterpret_cast<uint8_t*>(file_data.data()), file_data.size() }));
|
||||
canonical_path = file.canonical_path;
|
||||
|
|
Loading…
Reference in New Issue