Kernel: Make SharedInodeVMObject allocation OOM-safe

This commit is contained in:
Andreas Kling 2021-07-11 17:52:07 +02:00
parent 59049ae4b7
commit af8c74a328
Notes: sideshowbarker 2024-07-18 09:19:25 +09:00
4 changed files with 17 additions and 6 deletions

View file

@ -97,7 +97,7 @@ KResultOr<Region*> InodeFile::mmap(Process& process, FileDescription& descriptio
// FIXME: If PROT_EXEC, check that the underlying file system isn't mounted noexec. // FIXME: If PROT_EXEC, check that the underlying file system isn't mounted noexec.
RefPtr<InodeVMObject> vmobject; RefPtr<InodeVMObject> vmobject;
if (shared) if (shared)
vmobject = SharedInodeVMObject::create_with_inode(inode()); vmobject = SharedInodeVMObject::try_create_with_inode(inode());
else else
vmobject = PrivateInodeVMObject::create_with_inode(inode()); vmobject = PrivateInodeVMObject::create_with_inode(inode());
if (!vmobject) if (!vmobject)

View file

@ -162,7 +162,11 @@ struct RequiredLoadRange {
static KResultOr<RequiredLoadRange> get_required_load_range(FileDescription& program_description) static KResultOr<RequiredLoadRange> get_required_load_range(FileDescription& program_description)
{ {
auto& inode = *(program_description.inode()); auto& inode = *(program_description.inode());
auto vmobject = SharedInodeVMObject::create_with_inode(inode); auto vmobject = SharedInodeVMObject::try_create_with_inode(inode);
if (!vmobject) {
dbgln("get_required_load_range: Unable to allocate SharedInodeVMObject");
return ENOMEM;
}
size_t executable_size = inode.size(); size_t executable_size = inode.size();
@ -263,7 +267,12 @@ static KResultOr<LoadResult> load_elf_object(NonnullOwnPtr<Space> new_space, Fil
FlatPtr load_offset, ShouldAllocateTls should_allocate_tls, ShouldAllowSyscalls should_allow_syscalls) FlatPtr load_offset, ShouldAllocateTls should_allocate_tls, ShouldAllowSyscalls should_allow_syscalls)
{ {
auto& inode = *(object_description.inode()); auto& inode = *(object_description.inode());
auto vmobject = SharedInodeVMObject::create_with_inode(inode); auto vmobject = SharedInodeVMObject::try_create_with_inode(inode);
if (!vmobject) {
dbgln("load_elf_object: Unable to allocate SharedInodeVMObject");
return ENOMEM;
}
if (vmobject->writable_mappings()) { if (vmobject->writable_mappings()) {
dbgln("Refusing to execute a write-mapped program"); dbgln("Refusing to execute a write-mapped program");
return ETXTBSY; return ETXTBSY;

View file

@ -9,12 +9,14 @@
namespace Kernel { namespace Kernel {
NonnullRefPtr<SharedInodeVMObject> SharedInodeVMObject::create_with_inode(Inode& inode) RefPtr<SharedInodeVMObject> SharedInodeVMObject::try_create_with_inode(Inode& inode)
{ {
size_t size = inode.size(); size_t size = inode.size();
if (auto shared_vmobject = inode.shared_vmobject()) if (auto shared_vmobject = inode.shared_vmobject())
return shared_vmobject.release_nonnull(); return shared_vmobject.release_nonnull();
auto vmobject = adopt_ref(*new SharedInodeVMObject(inode, size)); auto vmobject = adopt_ref_if_nonnull(new (nothrow) SharedInodeVMObject(inode, size));
if (!vmobject)
return nullptr;
vmobject->inode().set_shared_vmobject(*vmobject); vmobject->inode().set_shared_vmobject(*vmobject);
return vmobject; return vmobject;
} }

View file

@ -16,7 +16,7 @@ class SharedInodeVMObject final : public InodeVMObject {
AK_MAKE_NONMOVABLE(SharedInodeVMObject); AK_MAKE_NONMOVABLE(SharedInodeVMObject);
public: public:
static NonnullRefPtr<SharedInodeVMObject> create_with_inode(Inode&); static RefPtr<SharedInodeVMObject> try_create_with_inode(Inode&);
virtual RefPtr<VMObject> clone() override; virtual RefPtr<VMObject> clone() override;
private: private: