mirror of
				https://github.com/Mbed-TLS/mbedtls.git
				synced 2025-11-03 20:33:16 +03:00 
			
		
		
		
	Signed-off-by: Shaun Case <warmsocks@gmail.com> Signed-off-by: Dave Rodgman <dave.rodgman@arm.com>
		
			
				
	
	
		
			138 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* BEGIN_HEADER */
 | 
						|
 | 
						|
#include "mbedtls/net_sockets.h"
 | 
						|
 | 
						|
#if defined(unix) || defined(__unix__) || defined(__unix) || \
 | 
						|
    defined(__APPLE__) || defined(__QNXNTO__) || \
 | 
						|
    defined(__HAIKU__) || defined(__midipix__)
 | 
						|
#define MBEDTLS_PLATFORM_IS_UNIXLIKE
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE)
 | 
						|
#include <sys/resource.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <sys/time.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#include <fcntl.h>
 | 
						|
#include <unistd.h>
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
#if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE)
 | 
						|
/** Open a file on the given file descriptor.
 | 
						|
 *
 | 
						|
 * This is disruptive if there is already something open on that descriptor.
 | 
						|
 * Caller beware.
 | 
						|
 *
 | 
						|
 * \param ctx           An initialized, but unopened socket context.
 | 
						|
 *                      On success, it refers to the opened file (\p wanted_fd).
 | 
						|
 * \param wanted_fd     The desired file descriptor.
 | 
						|
 *
 | 
						|
 * \return              \c 0 on success, a negative error code on error.
 | 
						|
 */
 | 
						|
static int open_file_on_fd( mbedtls_net_context *ctx, int wanted_fd )
 | 
						|
{
 | 
						|
    int got_fd = open( "/dev/null", O_RDONLY );
 | 
						|
    TEST_ASSERT( got_fd >= 0 );
 | 
						|
    if( got_fd != wanted_fd )
 | 
						|
    {
 | 
						|
        TEST_ASSERT( dup2( got_fd, wanted_fd ) >= 0 );
 | 
						|
        TEST_ASSERT( close( got_fd ) >= 0 );
 | 
						|
    }
 | 
						|
    ctx->fd = wanted_fd;
 | 
						|
    return( 0 );
 | 
						|
exit:
 | 
						|
    return( -1 );
 | 
						|
}
 | 
						|
#endif /* MBEDTLS_PLATFORM_IS_UNIXLIKE */
 | 
						|
 | 
						|
/* END_HEADER */
 | 
						|
 | 
						|
/* BEGIN_DEPENDENCIES
 | 
						|
 * depends_on:MBEDTLS_NET_C
 | 
						|
 * END_DEPENDENCIES
 | 
						|
 */
 | 
						|
 | 
						|
/* BEGIN_CASE */
 | 
						|
void context_init_free( int reinit )
 | 
						|
{
 | 
						|
    mbedtls_net_context ctx;
 | 
						|
 | 
						|
    mbedtls_net_init( &ctx );
 | 
						|
    mbedtls_net_free( &ctx );
 | 
						|
 | 
						|
    if( reinit )
 | 
						|
        mbedtls_net_init( &ctx );
 | 
						|
    mbedtls_net_free( &ctx );
 | 
						|
 | 
						|
    /* This test case always succeeds, functionally speaking. A plausible
 | 
						|
     * bug might trigger an invalid pointer dereference or a memory leak. */
 | 
						|
    goto exit;
 | 
						|
}
 | 
						|
/* END_CASE */
 | 
						|
 | 
						|
/* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_IS_UNIXLIKE */
 | 
						|
void poll_beyond_fd_setsize( )
 | 
						|
{
 | 
						|
    /* Test that mbedtls_net_poll does not misbehave when given a file
 | 
						|
     * descriptor greater or equal to FD_SETSIZE. This code is specific to
 | 
						|
     * platforms with a Unix-like select() function, which is where
 | 
						|
     * FD_SETSIZE is a concern. */
 | 
						|
 | 
						|
    struct rlimit rlim_nofile;
 | 
						|
    int restore_rlim_nofile = 0;
 | 
						|
    int ret;
 | 
						|
    mbedtls_net_context ctx;
 | 
						|
    uint8_t buf[1];
 | 
						|
 | 
						|
    mbedtls_net_init( &ctx );
 | 
						|
 | 
						|
    /* On many systems, by default, the maximum permitted file descriptor
 | 
						|
     * number is less than FD_SETSIZE. If so, raise the limit if
 | 
						|
     * possible.
 | 
						|
     *
 | 
						|
     * If the limit can't be raised, a file descriptor opened by the
 | 
						|
     * net_sockets module will be less than FD_SETSIZE, so the test
 | 
						|
     * is not necessary and we mark it as skipped.
 | 
						|
     * A file descriptor could still be higher than FD_SETSIZE if it was
 | 
						|
     * opened before the limit was lowered (which is something an application
 | 
						|
     * might do); but we don't do such things in our test code, so the unit
 | 
						|
     * test will run if it can.
 | 
						|
     */
 | 
						|
    TEST_ASSERT( getrlimit( RLIMIT_NOFILE, &rlim_nofile ) == 0 );
 | 
						|
    if( rlim_nofile.rlim_cur < FD_SETSIZE + 1 )
 | 
						|
    {
 | 
						|
        rlim_t old_rlim_cur = rlim_nofile.rlim_cur;
 | 
						|
        rlim_nofile.rlim_cur = FD_SETSIZE + 1;
 | 
						|
        TEST_ASSUME( setrlimit( RLIMIT_NOFILE, &rlim_nofile ) == 0 );
 | 
						|
        rlim_nofile.rlim_cur = old_rlim_cur;
 | 
						|
        restore_rlim_nofile = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    TEST_ASSERT( open_file_on_fd( &ctx, FD_SETSIZE ) == 0 );
 | 
						|
 | 
						|
    /* In principle, mbedtls_net_poll() with valid arguments should succeed.
 | 
						|
     * However, we know that on Unix-like platforms (and others), this function
 | 
						|
     * is implemented on top of select() and fd_set, which do not support
 | 
						|
     * file descriptors greater or equal to FD_SETSIZE. So we expect to hit
 | 
						|
     * this platform limitation.
 | 
						|
     *
 | 
						|
     * If mbedtls_net_poll() does not proprely check that ctx.fd is in range,
 | 
						|
     * it may still happen to return the expected failure code, but if this
 | 
						|
     * is problematic on the particular platform where the code is running,
 | 
						|
     * a memory sanitizer such as UBSan should catch it.
 | 
						|
     */
 | 
						|
    ret = mbedtls_net_poll( &ctx, MBEDTLS_NET_POLL_READ, 0 );
 | 
						|
    TEST_EQUAL( ret, MBEDTLS_ERR_NET_POLL_FAILED );
 | 
						|
 | 
						|
    /* mbedtls_net_recv_timeout() uses select() and fd_set in the same way. */
 | 
						|
    ret = mbedtls_net_recv_timeout( &ctx, buf, sizeof( buf ), 0 );
 | 
						|
    TEST_EQUAL( ret, MBEDTLS_ERR_NET_POLL_FAILED );
 | 
						|
 | 
						|
exit:
 | 
						|
    mbedtls_net_free( &ctx );
 | 
						|
    if( restore_rlim_nofile )
 | 
						|
        setrlimit( RLIMIT_NOFILE, &rlim_nofile );
 | 
						|
}
 | 
						|
/* END_CASE */
 |