| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /* 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 */
|