mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:17:42 +00:00
Kernel: Clarify ambiguous {File,Description}::absolute_path
Found due to smelly code in InodeFile::absolute_path. In particular, this replaces the following misleading methods: File::absolute_path This method *never* returns an actual path, and if called on an InodeFile (which is impossible), it would VERIFY_NOT_REACHED(). OpenFileDescription::try_serialize_absolute_path OpenFileDescription::absolute_path These methods do not guarantee to return an actual path (just like the other method), and just like Custody::absolute_path they do not guarantee accuracy. In particular, just renaming the method made a TOCTOU bug obvious. The new method signatures use KResultOr, just like try_serialize_absolute_path() already did.
This commit is contained in:
parent
88ca12f037
commit
c05c5a7ff4
28 changed files with 83 additions and 65 deletions
|
@ -140,18 +140,9 @@ Device::~Device()
|
||||||
VERIFY(m_state == State::BeingRemoved);
|
VERIFY(m_state == State::BeingRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
String Device::absolute_path() const
|
KResultOr<NonnullOwnPtr<KString>> Device::pseudo_path(const OpenFileDescription&) const
|
||||||
{
|
{
|
||||||
// FIXME: I assume we can't really provide a well known path in the kernel
|
return KString::try_create(String::formatted("device:{},{}", major(), minor()));
|
||||||
// because this is a violation of abstraction layers between userland and the
|
|
||||||
// kernel, but maybe the whole name of "absolute_path" is just wrong as this
|
|
||||||
// is really not an "absolute_path".
|
|
||||||
return String::formatted("device:{},{}", major(), minor());
|
|
||||||
}
|
|
||||||
|
|
||||||
String Device::absolute_path(const OpenFileDescription&) const
|
|
||||||
{
|
|
||||||
return absolute_path();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::process_next_queued_request(Badge<AsyncDeviceRequest>, const AsyncDeviceRequest& completed_request)
|
void Device::process_next_queued_request(Badge<AsyncDeviceRequest>, const AsyncDeviceRequest& completed_request)
|
||||||
|
|
|
@ -40,8 +40,7 @@ public:
|
||||||
unsigned major() const { return m_major; }
|
unsigned major() const { return m_major; }
|
||||||
unsigned minor() const { return m_minor; }
|
unsigned minor() const { return m_minor; }
|
||||||
|
|
||||||
virtual String absolute_path(const OpenFileDescription&) const override;
|
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;
|
||||||
virtual String absolute_path() const;
|
|
||||||
|
|
||||||
UserID uid() const { return m_uid; }
|
UserID uid() const { return m_uid; }
|
||||||
GroupID gid() const { return m_gid; }
|
GroupID gid() const { return m_gid; }
|
||||||
|
|
|
@ -30,4 +30,9 @@ KResultOr<Memory::Region*> AnonymousFile::mmap(Process& process, OpenFileDescrip
|
||||||
return process.address_space().allocate_region_with_vmobject(range, m_vmobject, offset, {}, prot, shared);
|
return process.address_space().allocate_region_with_vmobject(range, m_vmobject, offset, {}, prot, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KResultOr<NonnullOwnPtr<KString>> AnonymousFile::pseudo_path(const OpenFileDescription&) const
|
||||||
|
{
|
||||||
|
return KString::try_create(":anonymous-file:"sv);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual StringView class_name() const override { return "AnonymousFile"sv; }
|
virtual StringView class_name() const override { return "AnonymousFile"sv; }
|
||||||
virtual String absolute_path(const OpenFileDescription&) const override { return ":anonymous-file:"; }
|
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const;
|
||||||
virtual bool can_read(const OpenFileDescription&, size_t) const override { return false; }
|
virtual bool can_read(const OpenFileDescription&, size_t) const override { return false; }
|
||||||
virtual bool can_write(const OpenFileDescription&, size_t) const override { return false; }
|
virtual bool can_write(const OpenFileDescription&, size_t) const override { return false; }
|
||||||
virtual KResultOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override { return ENOTSUP; }
|
virtual KResultOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override { return ENOTSUP; }
|
||||||
|
|
|
@ -132,9 +132,9 @@ KResultOr<size_t> FIFO::write(OpenFileDescription& fd, u64, const UserOrKernelBu
|
||||||
return m_buffer->write(buffer, size);
|
return m_buffer->write(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
String FIFO::absolute_path(const OpenFileDescription&) const
|
KResultOr<NonnullOwnPtr<KString>> FIFO::pseudo_path(const OpenFileDescription&) const
|
||||||
{
|
{
|
||||||
return String::formatted("fifo:{}", m_fifo_id);
|
return KString::try_create(String::formatted("fifo:{}", m_fifo_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult FIFO::stat(::stat& st) const
|
KResult FIFO::stat(::stat& st) const
|
||||||
|
|
|
@ -45,7 +45,7 @@ private:
|
||||||
virtual KResult stat(::stat&) const override;
|
virtual KResult stat(::stat&) const override;
|
||||||
virtual bool can_read(const OpenFileDescription&, size_t) const override;
|
virtual bool can_read(const OpenFileDescription&, size_t) const override;
|
||||||
virtual bool can_write(const OpenFileDescription&, size_t) const override;
|
virtual bool can_write(const OpenFileDescription&, size_t) const override;
|
||||||
virtual String absolute_path(const OpenFileDescription&) const override;
|
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;
|
||||||
virtual StringView class_name() const override { return "FIFO"sv; }
|
virtual StringView class_name() const override { return "FIFO"sv; }
|
||||||
virtual bool is_fifo() const override { return true; }
|
virtual bool is_fifo() const override { return true; }
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,8 @@ public:
|
||||||
virtual KResultOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared);
|
virtual KResultOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared);
|
||||||
virtual KResult stat(::stat&) const { return EBADF; }
|
virtual KResult stat(::stat&) const { return EBADF; }
|
||||||
|
|
||||||
virtual String absolute_path(const OpenFileDescription&) const = 0;
|
// Although this might be better described "name" or "description", these terms already have other meanings.
|
||||||
|
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const = 0;
|
||||||
|
|
||||||
virtual KResult truncate(u64) { return EINVAL; }
|
virtual KResult truncate(u64) { return EINVAL; }
|
||||||
virtual KResult sync() { return EINVAL; }
|
virtual KResult sync() { return EINVAL; }
|
||||||
|
|
|
@ -89,15 +89,14 @@ KResultOr<Memory::Region*> InodeFile::mmap(Process& process, OpenFileDescription
|
||||||
vmobject = TRY(Memory::SharedInodeVMObject::try_create_with_inode(inode()));
|
vmobject = TRY(Memory::SharedInodeVMObject::try_create_with_inode(inode()));
|
||||||
else
|
else
|
||||||
vmobject = TRY(Memory::PrivateInodeVMObject::try_create_with_inode(inode()));
|
vmobject = TRY(Memory::PrivateInodeVMObject::try_create_with_inode(inode()));
|
||||||
auto path = TRY(description.try_serialize_absolute_path());
|
auto path = TRY(description.pseudo_path());
|
||||||
return process.address_space().allocate_region_with_vmobject(range, vmobject.release_nonnull(), offset, path->view(), prot, shared);
|
return process.address_space().allocate_region_with_vmobject(range, vmobject.release_nonnull(), offset, path->view(), prot, shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
String InodeFile::absolute_path(const OpenFileDescription& description) const
|
KResultOr<NonnullOwnPtr<KString>> InodeFile::pseudo_path(const OpenFileDescription&) const
|
||||||
{
|
{
|
||||||
|
// If it has an inode, then it has a path, and therefore the caller should have been able to get a custody at some point.
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
VERIFY(description.custody());
|
|
||||||
return description.absolute_path();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult InodeFile::truncate(u64 size)
|
KResult InodeFile::truncate(u64 size)
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
virtual KResultOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared) override;
|
virtual KResultOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared) override;
|
||||||
virtual KResult stat(::stat& buffer) const override { return inode().metadata().stat(buffer); }
|
virtual KResult stat(::stat& buffer) const override { return inode().metadata().stat(buffer); }
|
||||||
|
|
||||||
virtual String absolute_path(const OpenFileDescription&) const override;
|
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;
|
||||||
|
|
||||||
virtual KResult truncate(u64) override;
|
virtual KResult truncate(u64) override;
|
||||||
virtual KResult sync() override;
|
virtual KResult sync() override;
|
||||||
|
|
|
@ -81,9 +81,9 @@ KResult InodeWatcher::close()
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
String InodeWatcher::absolute_path(const OpenFileDescription&) const
|
KResultOr<NonnullOwnPtr<KString>> InodeWatcher::pseudo_path(const OpenFileDescription&) const
|
||||||
{
|
{
|
||||||
return String::formatted("InodeWatcher:({})", m_wd_to_watches.size());
|
return KString::try_create(String::formatted("InodeWatcher:({})", m_wd_to_watches.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InodeWatcher::notify_inode_event(Badge<Inode>, InodeIdentifier inode_id, InodeWatcherEvent::Type event_type, String const& name)
|
void InodeWatcher::notify_inode_event(Badge<Inode>, InodeIdentifier inode_id, InodeWatcherEvent::Type event_type, String const& name)
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
virtual KResultOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override { return EIO; }
|
virtual KResultOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override { return EIO; }
|
||||||
virtual KResult close() override;
|
virtual KResult close() override;
|
||||||
|
|
||||||
virtual String absolute_path(const OpenFileDescription&) const override;
|
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;
|
||||||
virtual StringView class_name() const override { return "InodeWatcher"sv; };
|
virtual StringView class_name() const override { return "InodeWatcher"sv; };
|
||||||
virtual bool is_inode_watcher() const override { return true; }
|
virtual bool is_inode_watcher() const override { return true; }
|
||||||
|
|
||||||
|
|
|
@ -349,19 +349,18 @@ KResult OpenFileDescription::close()
|
||||||
return m_file->close();
|
return m_file->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<NonnullOwnPtr<KString>> OpenFileDescription::try_serialize_absolute_path()
|
KResultOr<NonnullOwnPtr<KString>> OpenFileDescription::original_absolute_path() const
|
||||||
|
{
|
||||||
|
if (!m_custody)
|
||||||
|
return ENOENT;
|
||||||
|
return m_custody->try_serialize_absolute_path();
|
||||||
|
}
|
||||||
|
|
||||||
|
KResultOr<NonnullOwnPtr<KString>> OpenFileDescription::pseudo_path() const
|
||||||
{
|
{
|
||||||
if (m_custody)
|
if (m_custody)
|
||||||
return m_custody->try_serialize_absolute_path();
|
return m_custody->try_serialize_absolute_path();
|
||||||
// FIXME: Don't go through a String here!
|
return m_file->pseudo_path(*this);
|
||||||
return KString::try_create(m_file->absolute_path(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
String OpenFileDescription::absolute_path() const
|
|
||||||
{
|
|
||||||
if (m_custody)
|
|
||||||
return m_custody->absolute_path();
|
|
||||||
return m_file->absolute_path(*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InodeMetadata OpenFileDescription::metadata() const
|
InodeMetadata OpenFileDescription::metadata() const
|
||||||
|
|
|
@ -64,8 +64,8 @@ public:
|
||||||
|
|
||||||
KResultOr<NonnullOwnPtr<KBuffer>> read_entire_file();
|
KResultOr<NonnullOwnPtr<KBuffer>> read_entire_file();
|
||||||
|
|
||||||
KResultOr<NonnullOwnPtr<KString>> try_serialize_absolute_path();
|
KResultOr<NonnullOwnPtr<KString>> original_absolute_path() const;
|
||||||
String absolute_path() const;
|
KResultOr<NonnullOwnPtr<KString>> pseudo_path() const;
|
||||||
|
|
||||||
bool is_direct() const { return m_direct; }
|
bool is_direct() const { return m_direct; }
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,8 @@ KResult VirtualFileSystem::mount_root(FileSystem& fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_root_inode = root_inode;
|
m_root_inode = root_inode;
|
||||||
dmesgln("VirtualFileSystem: mounted root from {} ({})", fs.class_name(), static_cast<FileBackedFileSystem&>(fs).file_description().absolute_path());
|
auto pseudo_path = TRY(static_cast<FileBackedFileSystem&>(fs).file_description().pseudo_path());
|
||||||
|
dmesgln("VirtualFileSystem: mounted root from {} ({})", fs.class_name(), pseudo_path);
|
||||||
|
|
||||||
m_mounts.with_exclusive([&](auto& mounts) {
|
m_mounts.with_exclusive([&](auto& mounts) {
|
||||||
mounts.append(move(mount));
|
mounts.append(move(mount));
|
||||||
|
|
|
@ -365,15 +365,23 @@ private:
|
||||||
fs_object.add("readonly", fs.is_readonly());
|
fs_object.add("readonly", fs.is_readonly());
|
||||||
fs_object.add("mount_flags", mount.flags());
|
fs_object.add("mount_flags", mount.flags());
|
||||||
|
|
||||||
if (fs.is_file_backed())
|
if (fs.is_file_backed()) {
|
||||||
fs_object.add("source", static_cast<const FileBackedFileSystem&>(fs).file_description().absolute_path());
|
auto pseudo_path_or_error = static_cast<const FileBackedFileSystem&>(fs).file_description().pseudo_path();
|
||||||
else
|
if (pseudo_path_or_error.is_error()) {
|
||||||
|
// We're probably out of memory and should not attempt to continue.
|
||||||
|
result = pseudo_path_or_error.error();
|
||||||
|
return IterationDecision::Break;
|
||||||
|
}
|
||||||
|
fs_object.add("source", pseudo_path_or_error.value()->characters());
|
||||||
|
} else {
|
||||||
fs_object.add("source", "none");
|
fs_object.add("source", "none");
|
||||||
|
}
|
||||||
|
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
array.finish();
|
if (result == KSuccess)
|
||||||
return KSuccess;
|
array.finish();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -456,10 +456,10 @@ bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String IPv4Socket::absolute_path(const OpenFileDescription&) const
|
KResultOr<NonnullOwnPtr<KString>> IPv4Socket::pseudo_path(const OpenFileDescription&) const
|
||||||
{
|
{
|
||||||
if (m_role == Role::None)
|
if (m_role == Role::None)
|
||||||
return "socket";
|
return KString::try_create("socket"sv);
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
builder.append("socket:");
|
builder.append("socket:");
|
||||||
|
@ -485,7 +485,7 @@ String IPv4Socket::absolute_path(const OpenFileDescription&) const
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.to_string();
|
return KString::try_create(builder.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> user_value, socklen_t user_value_size)
|
KResult IPv4Socket::setsockopt(int level, int option, Userspace<const void*> user_value, socklen_t user_value_size)
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
|
|
||||||
IPv4SocketTuple tuple() const { return IPv4SocketTuple(m_local_address, m_local_port, m_peer_address, m_peer_port); }
|
IPv4SocketTuple tuple() const { return IPv4SocketTuple(m_local_address, m_local_port, m_peer_address, m_peer_port); }
|
||||||
|
|
||||||
String absolute_path(const OpenFileDescription& description) const override;
|
KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription& description) const override;
|
||||||
|
|
||||||
u8 type_of_service() const { return m_type_of_service; }
|
u8 type_of_service() const { return m_type_of_service; }
|
||||||
u8 ttl() const { return m_ttl; }
|
u8 ttl() const { return m_ttl; }
|
||||||
|
|
|
@ -355,7 +355,7 @@ StringView LocalSocket::socket_path() const
|
||||||
return m_path->view();
|
return m_path->view();
|
||||||
}
|
}
|
||||||
|
|
||||||
String LocalSocket::absolute_path(const OpenFileDescription& description) const
|
KResultOr<NonnullOwnPtr<KString>> LocalSocket::pseudo_path(const OpenFileDescription& description) const
|
||||||
{
|
{
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
builder.append("socket:");
|
builder.append("socket:");
|
||||||
|
@ -378,7 +378,7 @@ String LocalSocket::absolute_path(const OpenFileDescription& description) const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.to_string();
|
return KString::try_create(builder.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult LocalSocket::getsockopt(OpenFileDescription& description, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size)
|
KResult LocalSocket::getsockopt(OpenFileDescription& description, int level, int option, Userspace<void*> value, Userspace<socklen_t*> value_size)
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
static void for_each(Function<void(const LocalSocket&)>);
|
static void for_each(Function<void(const LocalSocket&)>);
|
||||||
|
|
||||||
StringView socket_path() const;
|
StringView socket_path() const;
|
||||||
String absolute_path(const OpenFileDescription& description) const override;
|
KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription& description) const override;
|
||||||
|
|
||||||
// ^Socket
|
// ^Socket
|
||||||
virtual KResult bind(Userspace<const sockaddr*>, socklen_t) override;
|
virtual KResult bind(Userspace<const sockaddr*>, socklen_t) override;
|
||||||
|
|
|
@ -105,7 +105,7 @@ public:
|
||||||
virtual KResultOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override final;
|
virtual KResultOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override final;
|
||||||
virtual KResultOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override final;
|
virtual KResultOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override final;
|
||||||
virtual KResult stat(::stat&) const override;
|
virtual KResult stat(::stat&) const override;
|
||||||
virtual String absolute_path(const OpenFileDescription&) const override = 0;
|
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override = 0;
|
||||||
|
|
||||||
bool has_receive_timeout() const { return m_receive_timeout != Time::zero(); }
|
bool has_receive_timeout() const { return m_receive_timeout != Time::zero(); }
|
||||||
const Time& receive_timeout() const { return m_receive_timeout; }
|
const Time& receive_timeout() const { return m_receive_timeout; }
|
||||||
|
|
|
@ -80,9 +80,10 @@ KResultOr<NonnullRefPtr<Inode>> Process::lookup_stacks_directory(const ProcFS& p
|
||||||
KResultOr<size_t> Process::procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const
|
KResultOr<size_t> Process::procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const
|
||||||
{
|
{
|
||||||
auto file_description = TRY(m_fds.open_file_description(fd));
|
auto file_description = TRY(m_fds.open_file_description(fd));
|
||||||
auto data = file_description->absolute_path();
|
// Note: These links are not guaranteed to point to actual VFS paths, just like in other kernels.
|
||||||
TRY(builder.append(data));
|
auto data = TRY(file_description->pseudo_path());
|
||||||
return data.length();
|
TRY(builder.append(data->view()));
|
||||||
|
return data->length();
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult Process::traverse_file_descriptions_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
|
KResult Process::traverse_file_descriptions_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
|
||||||
|
@ -187,7 +188,9 @@ KResult Process::procfs_get_fds_stats(KBufferBuilder& builder) const
|
||||||
RefPtr<OpenFileDescription> description = file_description_metadata.description();
|
RefPtr<OpenFileDescription> description = file_description_metadata.description();
|
||||||
auto description_object = array.add_object();
|
auto description_object = array.add_object();
|
||||||
description_object.add("fd", count);
|
description_object.add("fd", count);
|
||||||
description_object.add("absolute_path", description->absolute_path());
|
// TODO: Better OOM handling.
|
||||||
|
auto pseudo_path_or_error = description->pseudo_path();
|
||||||
|
description_object.add("absolute_path", pseudo_path_or_error.is_error() ? "???"sv : pseudo_path_or_error.value()->view());
|
||||||
description_object.add("seekable", description->file().is_seekable());
|
description_object.add("seekable", description->file().is_seekable());
|
||||||
description_object.add("class", description->file().class_name());
|
description_object.add("class", description->file().class_name());
|
||||||
description_object.add("offset", description->offset());
|
description_object.add("offset", description->offset());
|
||||||
|
|
|
@ -275,7 +275,7 @@ static KResultOr<LoadResult> load_elf_object(NonnullOwnPtr<Memory::AddressSpace>
|
||||||
size_t master_tls_alignment = 0;
|
size_t master_tls_alignment = 0;
|
||||||
FlatPtr load_base_address = 0;
|
FlatPtr load_base_address = 0;
|
||||||
|
|
||||||
auto elf_name = TRY(object_description.try_serialize_absolute_path());
|
auto elf_name = TRY(object_description.pseudo_path());
|
||||||
VERIFY(!Processor::in_critical());
|
VERIFY(!Processor::in_critical());
|
||||||
|
|
||||||
Memory::MemoryManager::enter_address_space(*new_space);
|
Memory::MemoryManager::enter_address_space(*new_space);
|
||||||
|
@ -438,7 +438,9 @@ KResult Process::do_exec(NonnullRefPtr<OpenFileDescription> main_program_descrip
|
||||||
{
|
{
|
||||||
VERIFY(is_user_process());
|
VERIFY(is_user_process());
|
||||||
VERIFY(!Processor::in_critical());
|
VERIFY(!Processor::in_critical());
|
||||||
auto path = TRY(main_program_description->try_serialize_absolute_path());
|
// Although we *could* handle a pseudo_path here, trying to execute something that doesn't have
|
||||||
|
// a custody (e.g. BlockDevice or RandomDevice) is pretty suspicious anyway.
|
||||||
|
auto path = TRY(main_program_description->original_absolute_path());
|
||||||
|
|
||||||
dbgln_if(EXEC_DEBUG, "do_exec: {}", path);
|
dbgln_if(EXEC_DEBUG, "do_exec: {}", path);
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,8 @@ KResultOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*>
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgln("mount: attempting to mount {} on {}", description->absolute_path(), target);
|
auto source_pseudo_path = TRY(description->pseudo_path());
|
||||||
|
dbgln("mount: attempting to mount {} on {}", source_pseudo_path, target);
|
||||||
|
|
||||||
fs = TRY(Ext2FS::try_create(*description));
|
fs = TRY(Ext2FS::try_create(*description));
|
||||||
} else if (fs_type == "9p"sv || fs_type == "Plan9FS"sv) {
|
} else if (fs_type == "9p"sv || fs_type == "Plan9FS"sv) {
|
||||||
|
@ -96,7 +97,8 @@ KResultOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*>
|
||||||
dbgln("mount: this is not a seekable file");
|
dbgln("mount: this is not a seekable file");
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
}
|
}
|
||||||
dbgln("mount: attempting to mount {} on {}", description->absolute_path(), target);
|
auto source_pseudo_path = TRY(description->pseudo_path());
|
||||||
|
dbgln("mount: attempting to mount {} on {}", source_pseudo_path, target);
|
||||||
fs = TRY(ISO9660FS::try_create(*description));
|
fs = TRY(ISO9660FS::try_create(*description));
|
||||||
} else {
|
} else {
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
|
|
@ -77,7 +77,9 @@ KResultOr<FlatPtr> Process::sys$fstatvfs(int fd, statvfs* buf)
|
||||||
REQUIRE_PROMISE(stdio);
|
REQUIRE_PROMISE(stdio);
|
||||||
|
|
||||||
auto description = TRY(fds().open_file_description(fd));
|
auto description = TRY(fds().open_file_description(fd));
|
||||||
return do_statvfs(description->absolute_path(), buf);
|
auto absolute_path = TRY(description->original_absolute_path());
|
||||||
|
// FIXME: TOCTOU bug! The file connected to the fd may or may not have been moved, and the name possibly taken by a different file.
|
||||||
|
return do_statvfs(absolute_path->view(), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,9 +127,10 @@ KResult MasterPTY::ioctl(OpenFileDescription& description, unsigned request, Use
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
String MasterPTY::absolute_path(const OpenFileDescription&) const
|
KResultOr<NonnullOwnPtr<KString>> MasterPTY::pseudo_path(const OpenFileDescription&) const
|
||||||
{
|
{
|
||||||
return String::formatted("ptm:{}", m_pts_name);
|
// FIXME: Replace this and others of this pattern by KString::formatted()
|
||||||
|
return KString::try_create(String::formatted("ptm:{}", m_pts_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
void notify_slave_closed(Badge<SlavePTY>);
|
void notify_slave_closed(Badge<SlavePTY>);
|
||||||
bool is_closed() const { return m_closed; }
|
bool is_closed() const { return m_closed; }
|
||||||
|
|
||||||
virtual String absolute_path(const OpenFileDescription&) const override;
|
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit MasterPTY(unsigned index, NonnullOwnPtr<DoubleBuffer> buffer);
|
explicit MasterPTY(unsigned index, NonnullOwnPtr<DoubleBuffer> buffer);
|
||||||
|
|
|
@ -576,6 +576,11 @@ KResult TTY::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KResultOr<NonnullOwnPtr<KString>> TTY::pseudo_path(const OpenFileDescription&) const
|
||||||
|
{
|
||||||
|
return KString::try_create(tty_name());
|
||||||
|
}
|
||||||
|
|
||||||
void TTY::set_size(unsigned short columns, unsigned short rows)
|
void TTY::set_size(unsigned short columns, unsigned short rows)
|
||||||
{
|
{
|
||||||
m_rows = rows;
|
m_rows = rows;
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
virtual bool can_read(const OpenFileDescription&, size_t) const override;
|
virtual bool can_read(const OpenFileDescription&, size_t) const override;
|
||||||
virtual bool can_write(const OpenFileDescription&, size_t) const override;
|
virtual bool can_write(const OpenFileDescription&, size_t) const override;
|
||||||
virtual KResult ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override final;
|
virtual KResult ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override final;
|
||||||
virtual String absolute_path(const OpenFileDescription&) const override { return tty_name(); }
|
virtual KResultOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;
|
||||||
|
|
||||||
virtual String const& tty_name() const = 0;
|
virtual String const& tty_name() const = 0;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue