mirror of
				https://github.com/yuzu-emu/mbedtls.git
				synced 2025-11-04 08:15:10 +00:00 
			
		
		
		
	Merge pull request #4180 from gilles-peskine-arm/net_poll-fd_setsize-2.16
Backport 2.16: Fix stack corruption in mbedtls_net_poll with large file descriptor
This commit is contained in:
		
						commit
						1b6a24f759
					
				
							
								
								
									
										4
									
								
								ChangeLog.d/net_poll-fd_setsize.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								ChangeLog.d/net_poll-fd_setsize.txt
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					Security
 | 
				
			||||||
 | 
					   * Fix a stack buffer overflow with mbedtls_net_poll() and
 | 
				
			||||||
 | 
					     mbedtls_net_recv_timeout() when given a file descriptor that is
 | 
				
			||||||
 | 
					     beyond FD_SETSIZE. Reported by FigBug in #4169.
 | 
				
			||||||
| 
						 | 
					@ -151,6 +151,7 @@ int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \return         0 if successful, or one of:
 | 
					 * \return         0 if successful, or one of:
 | 
				
			||||||
 *                      MBEDTLS_ERR_NET_SOCKET_FAILED,
 | 
					 *                      MBEDTLS_ERR_NET_SOCKET_FAILED,
 | 
				
			||||||
 | 
					 *                      MBEDTLS_ERR_NET_UNKNOWN_HOST,
 | 
				
			||||||
 *                      MBEDTLS_ERR_NET_BIND_FAILED,
 | 
					 *                      MBEDTLS_ERR_NET_BIND_FAILED,
 | 
				
			||||||
 *                      MBEDTLS_ERR_NET_LISTEN_FAILED
 | 
					 *                      MBEDTLS_ERR_NET_LISTEN_FAILED
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -170,6 +171,8 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
 | 
				
			||||||
 *                  can be NULL if client_ip is null
 | 
					 *                  can be NULL if client_ip is null
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \return          0 if successful, or
 | 
					 * \return          0 if successful, or
 | 
				
			||||||
 | 
					 *                  MBEDTLS_ERR_NET_SOCKET_FAILED,
 | 
				
			||||||
 | 
					 *                  MBEDTLS_ERR_NET_BIND_FAILED,
 | 
				
			||||||
 *                  MBEDTLS_ERR_NET_ACCEPT_FAILED, or
 | 
					 *                  MBEDTLS_ERR_NET_ACCEPT_FAILED, or
 | 
				
			||||||
 *                  MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
 | 
					 *                  MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
 | 
				
			||||||
 *                  MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
 | 
					 *                  MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
 | 
				
			||||||
| 
						 | 
					@ -182,6 +185,10 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \brief          Check and wait for the context to be ready for read/write
 | 
					 * \brief          Check and wait for the context to be ready for read/write
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * \note           The current implementation of this function uses
 | 
				
			||||||
 | 
					 *                 select() and returns an error if the file descriptor
 | 
				
			||||||
 | 
					 *                 is \c FD_SETSIZE or greater.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * \param ctx      Socket to check
 | 
					 * \param ctx      Socket to check
 | 
				
			||||||
 * \param rw       Bitflag composed of MBEDTLS_NET_POLL_READ and
 | 
					 * \param rw       Bitflag composed of MBEDTLS_NET_POLL_READ and
 | 
				
			||||||
 *                 MBEDTLS_NET_POLL_WRITE specifying the events
 | 
					 *                 MBEDTLS_NET_POLL_WRITE specifying the events
 | 
				
			||||||
| 
						 | 
					@ -263,16 +270,21 @@ int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len );
 | 
				
			||||||
 *                 'timeout' seconds. If no error occurs, the actual amount
 | 
					 *                 'timeout' seconds. If no error occurs, the actual amount
 | 
				
			||||||
 *                 read is returned.
 | 
					 *                 read is returned.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * \note           The current implementation of this function uses
 | 
				
			||||||
 | 
					 *                 select() and returns an error if the file descriptor
 | 
				
			||||||
 | 
					 *                 is \c FD_SETSIZE or greater.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * \param ctx      Socket
 | 
					 * \param ctx      Socket
 | 
				
			||||||
 * \param buf      The buffer to write to
 | 
					 * \param buf      The buffer to write to
 | 
				
			||||||
 * \param len      Maximum length of the buffer
 | 
					 * \param len      Maximum length of the buffer
 | 
				
			||||||
 * \param timeout  Maximum number of milliseconds to wait for data
 | 
					 * \param timeout  Maximum number of milliseconds to wait for data
 | 
				
			||||||
 *                 0 means no timeout (wait forever)
 | 
					 *                 0 means no timeout (wait forever)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \return         the number of bytes received,
 | 
					 * \return         The number of bytes received if successful.
 | 
				
			||||||
 *                 or a non-zero error code:
 | 
					 *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out.
 | 
				
			||||||
 *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
 | 
					 | 
				
			||||||
 *                 MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
 | 
					 *                 MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
 | 
				
			||||||
 | 
					 *                 Another negative error code (MBEDTLS_ERR_NET_xxx)
 | 
				
			||||||
 | 
					 *                 for other failures.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \note           This function will block (until data becomes available or
 | 
					 * \note           This function will block (until data becomes available or
 | 
				
			||||||
 *                 timeout is reached) even if the socket is set to
 | 
					 *                 timeout is reached) even if the socket is set to
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -496,6 +496,13 @@ int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
 | 
				
			||||||
    if( fd < 0 )
 | 
					    if( fd < 0 )
 | 
				
			||||||
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
					        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* A limitation of select() is that it only works with file descriptors
 | 
				
			||||||
 | 
					     * that are strictly less than FD_SETSIZE. This is a limitation of the
 | 
				
			||||||
 | 
					     * fd_set type. Error out early, because attempting to call FD_SET on a
 | 
				
			||||||
 | 
					     * large file descriptor is a buffer overflow on typical platforms. */
 | 
				
			||||||
 | 
					    if( fd >= FD_SETSIZE )
 | 
				
			||||||
 | 
					        return( MBEDTLS_ERR_NET_POLL_FAILED );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__has_feature)
 | 
					#if defined(__has_feature)
 | 
				
			||||||
#if __has_feature(memory_sanitizer)
 | 
					#if __has_feature(memory_sanitizer)
 | 
				
			||||||
    /* Ensure that memory sanitizers consider read_fds and write_fds as
 | 
					    /* Ensure that memory sanitizers consider read_fds and write_fds as
 | 
				
			||||||
| 
						 | 
					@ -615,6 +622,13 @@ int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
 | 
				
			||||||
    if( fd < 0 )
 | 
					    if( fd < 0 )
 | 
				
			||||||
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
					        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* A limitation of select() is that it only works with file descriptors
 | 
				
			||||||
 | 
					     * that are strictly less than FD_SETSIZE. This is a limitation of the
 | 
				
			||||||
 | 
					     * fd_set type. Error out early, because attempting to call FD_SET on a
 | 
				
			||||||
 | 
					     * large file descriptor is a buffer overflow on typical platforms. */
 | 
				
			||||||
 | 
					    if( fd >= FD_SETSIZE )
 | 
				
			||||||
 | 
					        return( MBEDTLS_ERR_NET_POLL_FAILED );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FD_ZERO( &read_fds );
 | 
					    FD_ZERO( &read_fds );
 | 
				
			||||||
    FD_SET( fd, &read_fds );
 | 
					    FD_SET( fd, &read_fds );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue