浏览代码

Kernel: Make SharedInodeVMObject allocation OOM-safe

Andreas Kling 4 年之前
父节点
当前提交
af8c74a328
共有 4 个文件被更改,包括 17 次插入6 次删除
  1. 1 1
      Kernel/FileSystem/InodeFile.cpp
  2. 11 2
      Kernel/Syscalls/execve.cpp
  3. 4 2
      Kernel/VM/SharedInodeVMObject.cpp
  4. 1 1
      Kernel/VM/SharedInodeVMObject.h

+ 1 - 1
Kernel/FileSystem/InodeFile.cpp

@@ -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.
     RefPtr<InodeVMObject> vmobject;
     if (shared)
-        vmobject = SharedInodeVMObject::create_with_inode(inode());
+        vmobject = SharedInodeVMObject::try_create_with_inode(inode());
     else
         vmobject = PrivateInodeVMObject::create_with_inode(inode());
     if (!vmobject)

+ 11 - 2
Kernel/Syscalls/execve.cpp

@@ -162,7 +162,11 @@ struct RequiredLoadRange {
 static KResultOr<RequiredLoadRange> get_required_load_range(FileDescription& program_description)
 {
     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();
 
@@ -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)
 {
     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()) {
         dbgln("Refusing to execute a write-mapped program");
         return ETXTBSY;

+ 4 - 2
Kernel/VM/SharedInodeVMObject.cpp

@@ -9,12 +9,14 @@
 
 namespace Kernel {
 
-NonnullRefPtr<SharedInodeVMObject> SharedInodeVMObject::create_with_inode(Inode& inode)
+RefPtr<SharedInodeVMObject> SharedInodeVMObject::try_create_with_inode(Inode& inode)
 {
     size_t size = inode.size();
     if (auto shared_vmobject = inode.shared_vmobject())
         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);
     return vmobject;
 }

+ 1 - 1
Kernel/VM/SharedInodeVMObject.h

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