diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-09-06 03:28:46 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-06 01:53:26 +0200 |
commit | 3a9f00c59bad7735970c72cb940d08161fda09b0 (patch) | |
tree | 5eebf972a2a3b3c2e73d40068f4d58c9d6368764 /Kernel | |
parent | 6606993432273959d7b2e1815646ee8a54025103 (diff) | |
download | serenity-3a9f00c59bad7735970c72cb940d08161fda09b0.zip |
Everywhere: Use OOM-safe ByteBuffer APIs where possible
If we can easily communicate failure, let's avoid asserting and report
failure instead.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Coredump.cpp | 79 | ||||
-rw-r--r-- | Kernel/Coredump.h | 10 |
2 files changed, 57 insertions, 32 deletions
diff --git a/Kernel/Coredump.cpp b/Kernel/Coredump.cpp index eb4657060d..acd044097c 100644 --- a/Kernel/Coredump.cpp +++ b/Kernel/Coredump.cpp @@ -198,13 +198,15 @@ KResult Coredump::write_notes_segment(ByteBuffer& notes_segment) return KSuccess; } -ByteBuffer Coredump::create_notes_process_data() const +KResultOr<ByteBuffer> Coredump::create_notes_process_data() const { ByteBuffer process_data; ELF::Core::ProcessInfo info {}; info.header.type = ELF::Core::NotesEntryHeader::Type::ProcessInfo; - process_data.append((void*)&info, sizeof(info)); + auto ok = process_data.try_append((void*)&info, sizeof(info)); + if (!ok) + return ENOMEM; StringBuilder builder; { @@ -227,18 +229,18 @@ ByteBuffer Coredump::create_notes_process_data() const } builder.append(0); - process_data.append(builder.string_view().characters_without_null_termination(), builder.length()); + ok = process_data.try_append(builder.string_view().characters_without_null_termination(), builder.length()); + if (!ok) + return ENOMEM; return process_data; } -ByteBuffer Coredump::create_notes_threads_data() const +KResultOr<ByteBuffer> Coredump::create_notes_threads_data() const { ByteBuffer threads_data; for (auto& thread : m_process->threads_for_coredump({})) { - ByteBuffer entry_buff; - ELF::Core::ThreadInfo info {}; info.header.type = ELF::Core::NotesEntryHeader::Type::ThreadInfo; info.tid = thread.tid().value(); @@ -246,20 +248,17 @@ ByteBuffer Coredump::create_notes_threads_data() const if (thread.current_trap()) copy_kernel_registers_into_ptrace_registers(info.regs, thread.get_register_dump_from_stack()); - entry_buff.append((void*)&info, sizeof(info)); - - threads_data += entry_buff; + if (!threads_data.try_append(&info, sizeof(info))) + return ENOMEM; } return threads_data; } -ByteBuffer Coredump::create_notes_regions_data() const +KResultOr<ByteBuffer> Coredump::create_notes_regions_data() const { ByteBuffer regions_data; size_t region_index = 0; for (auto& region : m_process->address_space().regions()) { - - ByteBuffer memory_region_info_buffer; ELF::Core::MemoryRegionInfo info {}; info.header.type = ELF::Core::NotesEntryHeader::Type::MemoryRegionInfo; @@ -267,28 +266,32 @@ ByteBuffer Coredump::create_notes_regions_data() const info.region_end = region->vaddr().offset(region->size()).get(); info.program_header_index = region_index++; - memory_region_info_buffer.append((void*)&info, sizeof(info)); + if (!regions_data.try_ensure_capacity(regions_data.size() + sizeof(info) + region->name().length() + 1)) + return ENOMEM; + + auto ok = regions_data.try_append((void*)&info, sizeof(info)); // NOTE: The region name *is* null-terminated, so the following is ok: auto name = region->name(); if (name.is_empty()) { char null_terminator = '\0'; - memory_region_info_buffer.append(&null_terminator, 1); + ok = ok && regions_data.try_append(&null_terminator, 1); } else { - memory_region_info_buffer.append(name.characters_without_null_termination(), name.length() + 1); + ok = ok && regions_data.try_append(name.characters_without_null_termination(), name.length() + 1); } - - regions_data += memory_region_info_buffer; + VERIFY(ok); } return regions_data; } -ByteBuffer Coredump::create_notes_metadata_data() const +KResultOr<ByteBuffer> Coredump::create_notes_metadata_data() const { ByteBuffer metadata_data; ELF::Core::Metadata metadata {}; metadata.header.type = ELF::Core::NotesEntryHeader::Type::Metadata; - metadata_data.append((void*)&metadata, sizeof(metadata)); + auto ok = metadata_data.try_append((void*)&metadata, sizeof(metadata)); + if (!ok) + return ENOMEM; StringBuilder builder; { @@ -298,23 +301,41 @@ ByteBuffer Coredump::create_notes_metadata_data() const }); } builder.append(0); - metadata_data.append(builder.string_view().characters_without_null_termination(), builder.length()); + ok = metadata_data.try_append(builder.string_view().characters_without_null_termination(), builder.length()); + if (!ok) + return ENOMEM; return metadata_data; } -ByteBuffer Coredump::create_notes_segment_data() const +KResultOr<ByteBuffer> Coredump::create_notes_segment_data() const { ByteBuffer notes_buffer; - notes_buffer += create_notes_process_data(); - notes_buffer += create_notes_threads_data(); - notes_buffer += create_notes_regions_data(); - notes_buffer += create_notes_metadata_data(); + if (auto result = create_notes_process_data(); result.is_error()) + return result; + else if (!notes_buffer.try_append(result.value())) + return ENOMEM; + + if (auto result = create_notes_threads_data(); result.is_error()) + return result; + else if (!notes_buffer.try_append(result.value())) + return ENOMEM; + + if (auto result = create_notes_regions_data(); result.is_error()) + return result; + else if (!notes_buffer.try_append(result.value())) + return ENOMEM; + + if (auto result = create_notes_metadata_data(); result.is_error()) + return result; + else if (!notes_buffer.try_append(result.value())) + return ENOMEM; ELF::Core::NotesEntryHeader null_entry {}; null_entry.type = ELF::Core::NotesEntryHeader::Type::Null; - notes_buffer.append(&null_entry, sizeof(null_entry)); + if (!notes_buffer.try_append(&null_entry, sizeof(null_entry))) + return ENOMEM; return notes_buffer; } @@ -324,7 +345,11 @@ KResult Coredump::write() SpinlockLocker lock(m_process->address_space().get_lock()); ProcessPagingScope scope(m_process); - ByteBuffer notes_segment = create_notes_segment_data(); + auto notes_segment_result = create_notes_segment_data(); + if (notes_segment_result.is_error()) + return notes_segment_result.error(); + + auto& notes_segment = notes_segment_result.value(); auto result = write_elf_header(); if (result.is_error()) diff --git a/Kernel/Coredump.h b/Kernel/Coredump.h index 9fb9200c57..de405fbe66 100644 --- a/Kernel/Coredump.h +++ b/Kernel/Coredump.h @@ -29,11 +29,11 @@ private: [[nodiscard]] KResult write_regions(); [[nodiscard]] KResult write_notes_segment(ByteBuffer&); - ByteBuffer create_notes_segment_data() const; - ByteBuffer create_notes_process_data() const; - ByteBuffer create_notes_threads_data() const; - ByteBuffer create_notes_regions_data() const; - ByteBuffer create_notes_metadata_data() const; + KResultOr<ByteBuffer> create_notes_segment_data() const; + KResultOr<ByteBuffer> create_notes_process_data() const; + KResultOr<ByteBuffer> create_notes_threads_data() const; + KResultOr<ByteBuffer> create_notes_regions_data() const; + KResultOr<ByteBuffer> create_notes_metadata_data() const; NonnullRefPtr<Process> m_process; NonnullRefPtr<FileDescription> m_fd; |