quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

test_suite_net.function (4412B)


      1 /* BEGIN_HEADER */
      2 
      3 #include "mbedtls/net_sockets.h"
      4 
      5 #if defined(unix) || defined(__unix__) || defined(__unix) || \
      6     defined(__APPLE__) || defined(__QNXNTO__) || \
      7     defined(__HAIKU__) || defined(__midipix__)
      8 #define MBEDTLS_PLATFORM_IS_UNIXLIKE
      9 #endif
     10 
     11 #if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE)
     12 #include <sys/resource.h>
     13 #include <sys/stat.h>
     14 #include <sys/time.h>
     15 #include <sys/types.h>
     16 #include <fcntl.h>
     17 #include <unistd.h>
     18 #endif
     19 
     20 
     21 #if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE)
     22 /** Open a file on the given file descriptor.
     23  *
     24  * This is disruptive if there is already something open on that descriptor.
     25  * Caller beware.
     26  *
     27  * \param ctx           An initialized, but unopened socket context.
     28  *                      On success, it refers to the opened file (\p wanted_fd).
     29  * \param wanted_fd     The desired file descriptor.
     30  *
     31  * \return              \c 0 on success, a negative error code on error.
     32  */
     33 static int open_file_on_fd(mbedtls_net_context *ctx, int wanted_fd)
     34 {
     35     int got_fd = open("/dev/null", O_RDONLY);
     36     TEST_ASSERT(got_fd >= 0);
     37     if (got_fd != wanted_fd) {
     38         TEST_ASSERT(dup2(got_fd, wanted_fd) >= 0);
     39         TEST_ASSERT(close(got_fd) >= 0);
     40     }
     41     ctx->fd = wanted_fd;
     42     return 0;
     43 exit:
     44     return -1;
     45 }
     46 #endif /* MBEDTLS_PLATFORM_IS_UNIXLIKE */
     47 
     48 /* END_HEADER */
     49 
     50 /* BEGIN_DEPENDENCIES
     51  * depends_on:MBEDTLS_NET_C
     52  * END_DEPENDENCIES
     53  */
     54 
     55 /* BEGIN_CASE */
     56 void context_init_free(int reinit)
     57 {
     58     mbedtls_net_context ctx;
     59 
     60     mbedtls_net_init(&ctx);
     61     mbedtls_net_free(&ctx);
     62 
     63     if (reinit) {
     64         mbedtls_net_init(&ctx);
     65     }
     66     mbedtls_net_free(&ctx);
     67 
     68     /* This test case always succeeds, functionally speaking. A plausible
     69      * bug might trigger an invalid pointer dereference or a memory leak. */
     70     goto exit;
     71 }
     72 /* END_CASE */
     73 
     74 /* BEGIN_CASE depends_on:MBEDTLS_PLATFORM_IS_UNIXLIKE */
     75 void poll_beyond_fd_setsize()
     76 {
     77     /* Test that mbedtls_net_poll does not misbehave when given a file
     78      * descriptor greater or equal to FD_SETSIZE. This code is specific to
     79      * platforms with a Unix-like select() function, which is where
     80      * FD_SETSIZE is a concern. */
     81 
     82     struct rlimit rlim_nofile;
     83     int restore_rlim_nofile = 0;
     84     int ret;
     85     mbedtls_net_context ctx;
     86     uint8_t buf[1];
     87 
     88     mbedtls_net_init(&ctx);
     89 
     90     /* On many systems, by default, the maximum permitted file descriptor
     91      * number is less than FD_SETSIZE. If so, raise the limit if
     92      * possible.
     93      *
     94      * If the limit can't be raised, a file descriptor opened by the
     95      * net_sockets module will be less than FD_SETSIZE, so the test
     96      * is not necessary and we mark it as skipped.
     97      * A file descriptor could still be higher than FD_SETSIZE if it was
     98      * opened before the limit was lowered (which is something an application
     99      * might do); but we don't do such things in our test code, so the unit
    100      * test will run if it can.
    101      */
    102     TEST_ASSERT(getrlimit(RLIMIT_NOFILE, &rlim_nofile) == 0);
    103     if (rlim_nofile.rlim_cur < FD_SETSIZE + 1) {
    104         rlim_t old_rlim_cur = rlim_nofile.rlim_cur;
    105         rlim_nofile.rlim_cur = FD_SETSIZE + 1;
    106         TEST_ASSUME(setrlimit(RLIMIT_NOFILE, &rlim_nofile) == 0);
    107         rlim_nofile.rlim_cur = old_rlim_cur;
    108         restore_rlim_nofile = 1;
    109     }
    110 
    111     TEST_ASSERT(open_file_on_fd(&ctx, FD_SETSIZE) == 0);
    112 
    113     /* In principle, mbedtls_net_poll() with valid arguments should succeed.
    114      * However, we know that on Unix-like platforms (and others), this function
    115      * is implemented on top of select() and fd_set, which do not support
    116      * file descriptors greater or equal to FD_SETSIZE. So we expect to hit
    117      * this platform limitation.
    118      *
    119      * If mbedtls_net_poll() does not proprely check that ctx.fd is in range,
    120      * it may still happen to return the expected failure code, but if this
    121      * is problematic on the particular platform where the code is running,
    122      * a memory sanitizer such as UBSan should catch it.
    123      */
    124     ret = mbedtls_net_poll(&ctx, MBEDTLS_NET_POLL_READ, 0);
    125     TEST_EQUAL(ret, MBEDTLS_ERR_NET_POLL_FAILED);
    126 
    127     /* mbedtls_net_recv_timeout() uses select() and fd_set in the same way. */
    128     ret = mbedtls_net_recv_timeout(&ctx, buf, sizeof(buf), 0);
    129     TEST_EQUAL(ret, MBEDTLS_ERR_NET_POLL_FAILED);
    130 
    131 exit:
    132     mbedtls_net_free(&ctx);
    133     if (restore_rlim_nofile) {
    134         setrlimit(RLIMIT_NOFILE, &rlim_nofile);
    135     }
    136 }
    137 /* END_CASE */