mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 12:32:43 +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
					
				
					 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling