diff --git a/ChangeLog.d/net_poll-fd_setsize.txt b/ChangeLog.d/net_poll-fd_setsize.txt new file mode 100644 index 000000000..23b11bb59 --- /dev/null +++ b/ChangeLog.d/net_poll-fd_setsize.txt @@ -0,0 +1,3 @@ +Security + * Fix a stack buffer overflow with mbedtls_net_recv_timeout() when given a + file descriptor that is beyond FD_SETSIZE. Reported by FigBug in #4169. diff --git a/library/net_sockets.c b/library/net_sockets.c index 2876f8fdd..e19d84a29 100644 --- a/library/net_sockets.c +++ b/library/net_sockets.c @@ -535,6 +535,13 @@ int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, if( fd < 0 ) return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + /* A limitation of select() is that it only works with file descriptors + * up to FD_SETSIZE. This is a limitation of the fd_set type. Error out + * early, because attempting to call FD_SET on a large file descriptor + * is a buffer overflow on typical platforms. */ + if( fd >= FD_SETSIZE ) + return( MBEDTLS_ERR_NET_RECV_FAILED ); + FD_ZERO( &read_fds ); FD_SET( fd, &read_fds );