test_suite_net.function 4.4 KB

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