mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Added GetSockOptName
Filter out and translate invalid sockopt names.
This commit is contained in:
		
							parent
							
								
									0a7d53692a
								
							
						
					
					
						commit
						b1f89408dd
					
				@ -295,6 +295,26 @@ union CTRSockAddr {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Filters valid sockopt names and converts from platform-specific name if necessary
 | 
				
			||||||
 | 
					static int GetSockOptName(u32 name) {
 | 
				
			||||||
 | 
					    switch(name) {
 | 
				
			||||||
 | 
					        case SO_RCVLOWAT:
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					            // LOWAT not supported by WinSock
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        case SO_REUSEADDR:
 | 
				
			||||||
 | 
					        case SO_SNDBUF:
 | 
				
			||||||
 | 
					        case SO_RCVBUF:
 | 
				
			||||||
 | 
					        case SO_TYPE:
 | 
				
			||||||
 | 
					        case SO_ERROR:
 | 
				
			||||||
 | 
					            return name;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            // all other options are either ineffectual or unsupported
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Holds info about the currently open sockets
 | 
					/// Holds info about the currently open sockets
 | 
				
			||||||
static std::unordered_map<u32, SocketHolder> open_sockets;
 | 
					static std::unordered_map<u32, SocketHolder> open_sockets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -728,19 +748,30 @@ static void GetSockOpt(Service::Interface* self) {
 | 
				
			|||||||
    u32* cmd_buffer = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buffer = Kernel::GetCommandBuffer();
 | 
				
			||||||
    u32 socket_handle = cmd_buffer[1];
 | 
					    u32 socket_handle = cmd_buffer[1];
 | 
				
			||||||
    u32 level = cmd_buffer[2];
 | 
					    u32 level = cmd_buffer[2];
 | 
				
			||||||
    u32 optname = cmd_buffer[3];
 | 
					    int optname = GetSockOptName(cmd_buffer[3]);
 | 
				
			||||||
    socklen_t optlen = (socklen_t)cmd_buffer[4];
 | 
					    socklen_t optlen = (socklen_t)cmd_buffer[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int ret = -1;
 | 
				
			||||||
 | 
					    int err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(optname < 0) {
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					        err = WSAEINVAL;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        err = EINVAL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        // 0x100 = static buffer offset (bytes)
 | 
					        // 0x100 = static buffer offset (bytes)
 | 
				
			||||||
        // + 0x4 = 2nd pointer (u32) position
 | 
					        // + 0x4 = 2nd pointer (u32) position
 | 
				
			||||||
        // >> 2  = convert to u32 offset instead of byte offset (cmd_buffer = u32*)
 | 
					        // >> 2  = convert to u32 offset instead of byte offset (cmd_buffer = u32*)
 | 
				
			||||||
        char *optval = reinterpret_cast<char *>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
 | 
					        char *optval = reinterpret_cast<char *>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int ret = ::getsockopt(socket_handle, level, optname, optval, &optlen);
 | 
					        ret = ::getsockopt(socket_handle, level, optname, optval, &optlen);
 | 
				
			||||||
    int err = 0;
 | 
					        err = 0;
 | 
				
			||||||
        if (ret == SOCKET_ERROR_VALUE) {
 | 
					        if (ret == SOCKET_ERROR_VALUE) {
 | 
				
			||||||
            err = TranslateError(GET_ERRNO);
 | 
					            err = TranslateError(GET_ERRNO);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buffer[0] = IPC::MakeHeader(0x11, 4, 2);
 | 
					    cmd_buffer[0] = IPC::MakeHeader(0x11, 4, 2);
 | 
				
			||||||
    cmd_buffer[1] = ret;
 | 
					    cmd_buffer[1] = ret;
 | 
				
			||||||
@ -752,15 +783,27 @@ static void SetSockOpt(Service::Interface* self) {
 | 
				
			|||||||
    u32* cmd_buffer = Kernel::GetCommandBuffer();
 | 
					    u32* cmd_buffer = Kernel::GetCommandBuffer();
 | 
				
			||||||
    u32 socket_handle = cmd_buffer[1];
 | 
					    u32 socket_handle = cmd_buffer[1];
 | 
				
			||||||
    u32 level = cmd_buffer[2];
 | 
					    u32 level = cmd_buffer[2];
 | 
				
			||||||
    u32 optname = cmd_buffer[3];
 | 
					    int optname = GetSockOptName(cmd_buffer[3]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int ret = -1;
 | 
				
			||||||
 | 
					    int err = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(optname < 0) {
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					        err = WSAEINVAL;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        err = EINVAL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        socklen_t optlen = static_cast<socklen_t>(cmd_buffer[4]);
 | 
					        socklen_t optlen = static_cast<socklen_t>(cmd_buffer[4]);
 | 
				
			||||||
        const char *optval = reinterpret_cast<const char *>(Memory::GetPointer(cmd_buffer[8]));
 | 
					        const char *optval = reinterpret_cast<const char *>(Memory::GetPointer(cmd_buffer[8]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int ret = static_cast<u32>(::setsockopt(socket_handle, level, optname, optval, optlen));
 | 
					        ret = static_cast<u32>(::setsockopt(socket_handle, level, optname, optval, optlen));
 | 
				
			||||||
    int err = 0;
 | 
					        err = 0;
 | 
				
			||||||
        if (ret == SOCKET_ERROR_VALUE) {
 | 
					        if (ret == SOCKET_ERROR_VALUE) {
 | 
				
			||||||
            err = TranslateError(GET_ERRNO);
 | 
					            err = TranslateError(GET_ERRNO);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cmd_buffer[0] = IPC::MakeHeader(0x12, 4, 4);
 | 
					    cmd_buffer[0] = IPC::MakeHeader(0x12, 4, 4);
 | 
				
			||||||
    cmd_buffer[1] = ret;
 | 
					    cmd_buffer[1] = ret;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user