Kernel: Return ENOMEM in more places

There are plenty of places in the kernel that aren't
checking if they actually got their allocation.

This fixes some of them, but definitely not all.

Fixes #3390
Fixes #3391

Also, let's make find_one_free_page() return nullptr
if it doesn't get a free index. This stops the kernel
crashing when out of memory and allows memory purging
to take place again.

Fixes #3487
This commit is contained in:
Luke 2020-09-16 18:47:47 +01:00 committed by Andreas Kling
parent 2229b13c97
commit 68b361bd21
9 changed files with 34 additions and 12 deletions

View file

@ -192,8 +192,9 @@ KResultOr<Region*> BXVGADevice::mmap(Process& process, FileDescription&, Virtual
0,
"BXVGA Framebuffer",
prot);
if (!region)
return KResult(-ENOMEM);
dbg() << "BXVGADevice: mmap with size " << region->size() << " at " << region->vaddr();
ASSERT(region);
return region;
}

View file

@ -68,8 +68,9 @@ KResultOr<Region*> MBVGADevice::mmap(Process& process, FileDescription&, Virtual
0,
"MBVGA Framebuffer",
prot);
if (!region)
return KResult(-ENOMEM);
dbg() << "MBVGADevice: mmap with size " << region->size() << " at " << region->vaddr();
ASSERT(region);
return region;
}

View file

@ -235,8 +235,12 @@ KResultOr<size_t> SB16::write(FileDescription&, size_t, const UserOrKernelBuffer
{
if (!m_dma_region) {
auto page = MM.allocate_supervisor_physical_page();
if (!page)
return KResult(-ENOMEM);
auto vmobject = AnonymousVMObject::create_with_physical_page(*page);
m_dma_region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_SIZE, "SB16 DMA buffer", Region::Access::Write);
if (!m_dma_region)
return KResult(-ENOMEM);
}
#ifdef SB16_DEBUG
@ -245,7 +249,7 @@ KResultOr<size_t> SB16::write(FileDescription&, size_t, const UserOrKernelBuffer
ASSERT(length <= PAGE_SIZE);
const int BLOCK_SIZE = 32 * 1024;
if (length > BLOCK_SIZE) {
return -ENOSPC;
return KResult(-ENOSPC);
}
u8 mode = (u8)SampleFormat::Signed | (u8)SampleFormat::Stereo;

View file

@ -244,6 +244,10 @@ bool APIC::init_bsp()
set_base(apic_base);
m_apic_base = MM.allocate_kernel_region(apic_base.page_base(), PAGE_ROUND_UP(1), {}, Region::Access::Read | Region::Access::Write);
if (!m_apic_base) {
klog() << "APIC: Failed to allocate memory for APIC base";
return false;
}
auto rsdp = ACPI::StaticParsing::find_rsdp();
if (!rsdp.has_value()) {

View file

@ -267,7 +267,10 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
// NOTE: We create the new stack before disabling interrupts since it will zero-fault
// and we don't want to deal with faults after this point.
u32 new_userspace_esp = new_main_thread->make_userspace_stack_for_main_thread(move(arguments), move(environment), move(auxv));
auto make_stack_result = new_main_thread->make_userspace_stack_for_main_thread(move(arguments), move(environment), move(auxv));
if (make_stack_result.is_error())
return make_stack_result.error();
u32 new_userspace_esp = make_stack_result.value();
if (wait_for_tracer_at_next_execve())
Thread::current()->send_urgent_signal_to_self(SIGSTOP);
@ -287,7 +290,9 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
// FIXME: PID/TID ISSUE
m_pid = new_main_thread->tid().value();
new_main_thread->make_thread_specific_region({});
auto tsr_result = new_main_thread->make_thread_specific_region({});
if (tsr_result.is_error())
return tsr_result.error();
new_main_thread->reset_fpu_state();
auto& tss = new_main_thread->m_tss;

View file

@ -79,7 +79,9 @@ int Process::sys$create_thread(void* (*entry)(void*), Userspace<const Syscall::S
tss.cr3 = page_directory().cr3();
tss.esp = (u32)user_stack_address;
thread->make_thread_specific_region({});
auto tsr_result = thread->make_thread_specific_region({});
if (tsr_result.is_error())
return tsr_result.error();
thread->set_state(Thread::State::Runnable);
return thread->tid().value();
}

View file

@ -671,10 +671,11 @@ RegisterState& Thread::get_register_dump_from_stack()
return *(RegisterState*)(kernel_stack_top() - sizeof(RegisterState));
}
u32 Thread::make_userspace_stack_for_main_thread(Vector<String> arguments, Vector<String> environment, Vector<AuxiliaryValue> auxiliary_values)
KResultOr<u32> Thread::make_userspace_stack_for_main_thread(Vector<String> arguments, Vector<String> environment, Vector<AuxiliaryValue> auxiliary_values)
{
auto* region = m_process->allocate_region(VirtualAddress(), default_userspace_stack_size, "Stack (Main thread)", PROT_READ | PROT_WRITE, false);
ASSERT(region);
if (!region)
return KResult(-ENOMEM);
region->set_stack(true);
FlatPtr new_esp = region->vaddr().offset(default_userspace_stack_size).get();
@ -925,11 +926,13 @@ Vector<FlatPtr> Thread::raw_backtrace(FlatPtr ebp, FlatPtr eip) const
return backtrace;
}
void Thread::make_thread_specific_region(Badge<Process>)
KResult Thread::make_thread_specific_region(Badge<Process>)
{
size_t thread_specific_region_alignment = max(process().m_master_tls_alignment, alignof(ThreadSpecificData));
m_thread_specific_region_size = align_up_to(process().m_master_tls_size, thread_specific_region_alignment) + sizeof(ThreadSpecificData);
auto* region = process().allocate_region({}, m_thread_specific_region_size, "Thread-specific", PROT_READ | PROT_WRITE, true);
if (!region)
return KResult(-ENOMEM);
SmapDisabler disabler;
auto* thread_specific_data = (ThreadSpecificData*)region->vaddr().offset(align_up_to(process().m_master_tls_size, thread_specific_region_alignment)).as_ptr();
auto* thread_local_storage = (u8*)((u8*)thread_specific_data) - align_up_to(process().m_master_tls_size, process().m_master_tls_alignment);
@ -937,6 +940,7 @@ void Thread::make_thread_specific_region(Badge<Process>)
thread_specific_data->self = thread_specific_data;
if (process().m_master_tls_size)
memcpy(thread_local_storage, process().m_master_tls_region->vaddr().as_ptr(), process().m_master_tls_size);
return KSuccess;
}
const LogStream& operator<<(const LogStream& stream, const Thread& value)

View file

@ -433,9 +433,9 @@ public:
void set_default_signal_dispositions();
bool push_value_on_stack(FlatPtr);
u32 make_userspace_stack_for_main_thread(Vector<String> arguments, Vector<String> environment, Vector<AuxiliaryValue>);
KResultOr<u32> make_userspace_stack_for_main_thread(Vector<String> arguments, Vector<String> environment, Vector<AuxiliaryValue>);
void make_thread_specific_region(Badge<Process>);
KResult make_thread_specific_region(Badge<Process>);
unsigned syscall_count() const { return m_syscall_count; }
void did_syscall() { ++m_syscall_count; }

View file

@ -105,7 +105,8 @@ Optional<unsigned> PhysicalRegion::find_one_free_page()
return {};
}
auto free_index = m_bitmap.find_one_anywhere_unset(m_free_hint);
ASSERT(free_index.has_value());
if (!free_index.has_value())
return {};
auto page_index = free_index.value();
m_bitmap.set(page_index, true);