mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:42:44 +00:00 
			
		
		
		
	Kernel: Remove SmapDisablers in sys$getsockname() and sys$getpeername()
Instead use the user/kernel copy helpers to only copy the minimum stuff needed from to/from userspace. Based on work started by Brian Gianforcaro.
This commit is contained in:
		
							parent
							
								
									7454926765
								
							
						
					
					
						commit
						f4302b58fb
					
				
					 3 changed files with 44 additions and 36 deletions
				
			
		|  | @ -3214,19 +3214,23 @@ ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* user_params) | |||
|     return nrecv; | ||||
| } | ||||
| 
 | ||||
| int Process::sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen) | ||||
| template<bool sockname, typename Params> | ||||
| int Process::get_sock_or_peer_name(const Params& params) | ||||
| { | ||||
|     if (!validate_read_typed(addrlen)) | ||||
|     socklen_t addrlen_value; | ||||
|     if (!validate_read_and_copy_typed(&addrlen_value, params.addrlen)) | ||||
|         return -EFAULT; | ||||
| 
 | ||||
|     SmapDisabler disabler; | ||||
|     if (*addrlen <= 0) | ||||
|     if (addrlen_value <= 0) | ||||
|         return -EINVAL; | ||||
| 
 | ||||
|     if (!validate_write(addr, *addrlen)) | ||||
|     if (!validate_write(params.addr, addrlen_value)) | ||||
|         return -EFAULT; | ||||
| 
 | ||||
|     auto description = file_description(sockfd); | ||||
|     if (!validate_write_typed(params.addrlen)) | ||||
|         return -EFAULT; | ||||
| 
 | ||||
|     auto description = file_description(params.sockfd); | ||||
|     if (!description) | ||||
|         return -EBADF; | ||||
| 
 | ||||
|  | @ -3235,42 +3239,31 @@ int Process::sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen) | |||
| 
 | ||||
|     auto& socket = *description->socket(); | ||||
|     REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); | ||||
|     if (!socket.get_local_address(addr, addrlen)) | ||||
|         return -EINVAL; // FIXME: Should this be another error? I'm not sure.
 | ||||
| 
 | ||||
|     u8 address_buffer[sizeof(sockaddr_un)]; | ||||
|     addrlen_value = min(sizeof(sockaddr_un), static_cast<size_t>(addrlen_value)); | ||||
| 
 | ||||
|     if (!socket.get_local_address((sockaddr*)address_buffer, &addrlen_value)) | ||||
|         return -EINVAL; | ||||
| 
 | ||||
|     copy_to_user(params.addr, address_buffer, addrlen_value); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int Process::sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen) | ||||
| int Process::sys$getsockname(const Syscall::SC_getsockname_params* user_params) | ||||
| { | ||||
|     if (!validate_read_typed(addrlen)) | ||||
|     Syscall::SC_getsockname_params params; | ||||
|     if (!validate_read_and_copy_typed(¶ms, user_params)) | ||||
|         return -EFAULT; | ||||
|     return get_sock_or_peer_name<true>(params); | ||||
| } | ||||
| 
 | ||||
|     SmapDisabler disabler; | ||||
| 
 | ||||
|     if (*addrlen <= 0) | ||||
|         return -EINVAL; | ||||
| 
 | ||||
|     if (!validate_write(addr, *addrlen)) | ||||
| int Process::sys$getpeername(const Syscall::SC_getpeername_params* user_params) | ||||
| { | ||||
|     Syscall::SC_getpeername_params params; | ||||
|     if (!validate_read_and_copy_typed(¶ms, user_params)) | ||||
|         return -EFAULT; | ||||
| 
 | ||||
|     auto description = file_description(sockfd); | ||||
|     if (!description) | ||||
|         return -EBADF; | ||||
| 
 | ||||
|     if (!description->is_socket()) | ||||
|         return -ENOTSOCK; | ||||
| 
 | ||||
|     auto& socket = *description->socket(); | ||||
|     REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); | ||||
| 
 | ||||
|     if (socket.setup_state() != Socket::SetupState::Completed) | ||||
|         return -ENOTCONN; | ||||
| 
 | ||||
|     if (!socket.get_peer_address(addr, addrlen)) | ||||
|         return -EINVAL; // FIXME: Should this be another error? I'm not sure.
 | ||||
| 
 | ||||
|     return 0; | ||||
|     return get_sock_or_peer_name<false>(params); | ||||
| } | ||||
| 
 | ||||
| int Process::sys$sched_setparam(int tid, const struct sched_param* param) | ||||
|  |  | |||
|  | @ -263,8 +263,8 @@ public: | |||
|     ssize_t sys$recvfrom(const Syscall::SC_recvfrom_params*); | ||||
|     int sys$getsockopt(const Syscall::SC_getsockopt_params*); | ||||
|     int sys$setsockopt(const Syscall::SC_setsockopt_params*); | ||||
|     int sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen); | ||||
|     int sys$getpeername(int sockfd, sockaddr* addr, socklen_t* addrlen); | ||||
|     int sys$getsockname(const Syscall::SC_getsockname_params*); | ||||
|     int sys$getpeername(const Syscall::SC_getpeername_params*); | ||||
|     int sys$sched_setparam(pid_t pid, const struct sched_param* param); | ||||
|     int sys$sched_getparam(pid_t pid, struct sched_param* param); | ||||
|     int sys$create_thread(void* (*)(void*), void* argument, const Syscall::SC_create_thread_params*); | ||||
|  | @ -302,6 +302,9 @@ public: | |||
|     int sys$pledge(const Syscall::SC_pledge_params*); | ||||
|     int sys$unveil(const Syscall::SC_unveil_params*); | ||||
| 
 | ||||
|     template<bool sockname, typename Params> | ||||
|     int get_sock_or_peer_name(const Params&); | ||||
| 
 | ||||
|     static void initialize(); | ||||
| 
 | ||||
|     [[noreturn]] void crash(int signal, u32 eip); | ||||
|  |  | |||
|  | @ -297,6 +297,18 @@ struct SC_setsockopt_params { | |||
|     socklen_t value_size; | ||||
| }; | ||||
| 
 | ||||
| struct SC_getsockname_params { | ||||
|     int sockfd; | ||||
|     sockaddr* addr; | ||||
|     socklen_t* addrlen; | ||||
| }; | ||||
| 
 | ||||
| struct SC_getpeername_params { | ||||
|     int sockfd; | ||||
|     sockaddr* addr; | ||||
|     socklen_t* addrlen; | ||||
| }; | ||||
| 
 | ||||
| struct SC_futex_params { | ||||
|     i32* userspace_address; | ||||
|     int futex_op; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling