File: test_suite_net.function

package info (click to toggle)
edk2 2025.02-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 271,704 kB
  • sloc: ansic: 2,109,987; asm: 263,832; perl: 227,730; python: 149,919; sh: 34,967; cpp: 21,813; makefile: 3,282; xml: 806; pascal: 721; lisp: 35; ruby: 16; sed: 6; tcl: 4
file content (137 lines) | stat: -rw-r--r-- 4,467 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* 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 */