diff --git a/library/x509_crt.c b/library/x509_crt.c index 911644b7da..97a908c134 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -77,6 +77,7 @@ #include #include #include +#include #endif /* !_WIN32 || EFIX64 || EFI32 */ #endif @@ -1638,10 +1639,39 @@ cleanup: ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; goto cleanup; } - else if( stat( entry_name, &sb ) == -1 ) + else { - ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; - goto cleanup; + /* determinate if the file entry could be a link, using lstat(2) + * is safer than just stat(2), otherwise a broken link will + * give us a false positive. */ + if( lstat( entry_name, &sb ) == -1 ) + { + ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; + goto cleanup; + } + + /* if the file is a symbolic link, we need to validate the real + * information using stat(2). */ + if( S_ISLNK( sb.st_mode ) ) + { + /* if stat(2) fails it could be a broken link or a generic + * error, if the link is broken, just report it as a + * certificate that could not be processed, otherwise + * just set a MBEDTLS_ERR_X509_FILE_IO_ERROR. */ + if( stat( entry_name, &sb ) == -1 ) + { + if( errno == ENOENT ) + { + /* Broken link */ + ret++; + } + else + { + ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; + goto cleanup; + } + } + } } if( !S_ISREG( sb.st_mode ) )