mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
Kernel+LibC: Add minherit() and MAP_INHERIT_ZERO
This patch adds the minherit() syscall originally invented by OpenBSD. Only the MAP_INHERIT_ZERO mode is supported for now. If set on an mmap region, that region will be zeroed out on fork().
This commit is contained in:
parent
dd00175ae2
commit
c19b56dc99
Notes:
sideshowbarker
2024-07-19 07:40:10 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c19b56dc990
8 changed files with 58 additions and 1 deletions
|
@ -632,6 +632,32 @@ int Process::sys$madvise(void* address, size_t size, int advice)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
int Process::sys$minherit(void* address, size_t size, int inherit)
|
||||
{
|
||||
REQUIRE_PROMISE(stdio);
|
||||
|
||||
auto* region = region_from_range({ VirtualAddress(address), size });
|
||||
if (!region)
|
||||
return -EINVAL;
|
||||
|
||||
if (!region->is_mmap())
|
||||
return -EINVAL;
|
||||
|
||||
if (region->is_shared())
|
||||
return -EINVAL;
|
||||
|
||||
if (!region->vmobject().is_anonymous())
|
||||
return -EINVAL;
|
||||
|
||||
switch (inherit) {
|
||||
case MAP_INHERIT_ZERO:
|
||||
region->set_inherit_mode(Region::InheritMode::ZeroedOnFork);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int Process::sys$purge(int mode)
|
||||
{
|
||||
REQUIRE_NO_PROMISES;
|
||||
|
|
|
@ -204,6 +204,7 @@ public:
|
|||
int sys$set_mmap_name(const Syscall::SC_set_mmap_name_params*);
|
||||
int sys$mprotect(void*, size_t, int prot);
|
||||
int sys$madvise(void*, size_t, int advice);
|
||||
int sys$minherit(void*, size_t, int inherit);
|
||||
int sys$purge(int mode);
|
||||
int sys$select(const Syscall::SC_select_params*);
|
||||
int sys$poll(pollfd*, int nfds, int timeout);
|
||||
|
|
|
@ -182,7 +182,8 @@ namespace Kernel {
|
|||
__ENUMERATE_SYSCALL(perf_event) \
|
||||
__ENUMERATE_SYSCALL(shutdown) \
|
||||
__ENUMERATE_SYSCALL(get_stack_bounds) \
|
||||
__ENUMERATE_SYSCALL(ptrace)
|
||||
__ENUMERATE_SYSCALL(ptrace) \
|
||||
__ENUMERATE_SYSCALL(minherit)
|
||||
|
||||
namespace Syscall {
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@
|
|||
#define MADV_SET_NONVOLATILE 0x200
|
||||
#define MADV_GET_VOLATILE 0x400
|
||||
|
||||
#define MAP_INHERIT_ZERO 1
|
||||
|
||||
#define F_DUPFD 0
|
||||
#define F_GETFD 1
|
||||
#define F_SETFD 2
|
||||
|
|
|
@ -68,6 +68,16 @@ NonnullOwnPtr<Region> Region::clone()
|
|||
{
|
||||
ASSERT(Process::current);
|
||||
|
||||
if (m_inherit_mode == InheritMode::ZeroedOnFork) {
|
||||
ASSERT(m_mmap);
|
||||
ASSERT(!m_shared);
|
||||
ASSERT(vmobject().is_anonymous());
|
||||
auto zeroed_region = Region::create_user_accessible(m_range, AnonymousVMObject::create_with_size(size()), 0, m_name, m_access);
|
||||
zeroed_region->set_mmap(m_mmap);
|
||||
zeroed_region->set_inherit_mode(m_inherit_mode);
|
||||
return zeroed_region;
|
||||
}
|
||||
|
||||
if (m_shared) {
|
||||
ASSERT(!m_stack);
|
||||
#ifdef MM_DEBUG
|
||||
|
|
|
@ -55,6 +55,11 @@ public:
|
|||
Execute = 4,
|
||||
};
|
||||
|
||||
enum class InheritMode {
|
||||
Default,
|
||||
ZeroedOnFork,
|
||||
};
|
||||
|
||||
static NonnullOwnPtr<Region> create_user_accessible(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, const StringView& name, u8 access, bool cacheable = true);
|
||||
static NonnullOwnPtr<Region> create_kernel_only(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, const StringView& name, u8 access, bool cacheable = true);
|
||||
|
||||
|
@ -160,6 +165,8 @@ public:
|
|||
// NOTE: These are public so we can make<> them.
|
||||
Region(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, const String&, u8 access, bool cacheable);
|
||||
|
||||
void set_inherit_mode(InheritMode inherit_mode) { m_inherit_mode = inherit_mode; }
|
||||
|
||||
private:
|
||||
Bitmap& ensure_cow_map() const;
|
||||
|
||||
|
@ -183,6 +190,7 @@ private:
|
|||
NonnullRefPtr<VMObject> m_vmobject;
|
||||
String m_name;
|
||||
u8 m_access { 0 };
|
||||
InheritMode m_inherit_mode : 3 { InheritMode::Default };
|
||||
bool m_shared : 1 { false };
|
||||
bool m_user_accessible : 1 { false };
|
||||
bool m_cacheable : 1 { false };
|
||||
|
|
|
@ -81,4 +81,10 @@ int madvise(void* address, size_t size, int advice)
|
|||
int rc = syscall(SC_madvise, address, size, advice);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
|
||||
int minherit(void* address, size_t size, int inherit)
|
||||
{
|
||||
int rc = syscall(SC_minherit, address, size, inherit);
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
#define MADV_SET_NONVOLATILE 0x200
|
||||
#define MADV_GET_VOLATILE 0x400
|
||||
|
||||
#define MAP_INHERIT_ZERO 1
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
void* mmap(void* addr, size_t, int prot, int flags, int fd, off_t);
|
||||
|
@ -58,5 +60,6 @@ int munmap(void*, size_t);
|
|||
int mprotect(void*, size_t, int prot);
|
||||
int set_mmap_name(void*, size_t, const char*);
|
||||
int madvise(void*, size_t, int advice);
|
||||
int minherit(void*, size_t, int inherit);
|
||||
|
||||
__END_DECLS
|
||||
|
|
Loading…
Reference in a new issue