1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-16 19:15:07 +00:00
serenity/Kernel/SharedBuffer.h
Robin Burchell 2d4d465206 SharedBuffer: Fix a denial of service
It's a very bad idea to increment the refcount on behalf of another
process. That process may (for either benign or evil reasons) not
reference the SharedBuffer, and then we'll be stuck with loads of
SharedBuffers until we OOM.

Instead, increment the refcount when the buffer is mapped. That way, a
buffer is only kept if *someone* has explicitly requested it via
get_shared_buffer.

Fixes #341
2019-07-19 19:06:28 +02:00

51 lines
1.2 KiB
C++

#pragma once
#include <Kernel/VM/MemoryManager.h>
#include <AK/OwnPtr.h>
struct SharedBuffer {
private:
struct Reference {
Reference(pid_t pid)
: pid(pid)
{
}
pid_t pid;
unsigned count { 0 };
Region* region { nullptr };
};
public:
SharedBuffer(int id, int size)
: m_shared_buffer_id(id)
, m_vmo(VMObject::create_anonymous(size))
{
#ifdef SHARED_BUFFER_DEBUG
dbgprintf("Created shared buffer %d of size %d\n", m_shared_buffer_id, size);
#endif
}
~SharedBuffer()
{
#ifdef SHARED_BUFFER_DEBUG
dbgprintf("Destroyed shared buffer %d of size %d\n", m_shared_buffer_id, size());
#endif
}
bool is_shared_with(pid_t peer_pid);
void* ref_for_process_and_get_address(Process& process);
void share_with(pid_t peer_pid);
void deref_for_process(Process& process);
void disown(pid_t pid);
size_t size() const { return m_vmo->size(); }
void destroy_if_unused();
void seal();
int m_shared_buffer_id { -1 };
bool m_writable { true };
NonnullRefPtr<VMObject> m_vmo;
Vector<Reference, 2> m_refs;
unsigned m_total_refs { 0 };
};
Lockable<HashMap<int, OwnPtr<SharedBuffer>>>& shared_buffers();