-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mbed TLS 1.3: Fix compilation warnings with VS2015 x64 #999
mbed TLS 1.3: Fix compilation warnings with VS2015 x64 #999
Conversation
The warning was caused because of conversions from size_t to int, which can cause data loss. The files affected are: * ssl_client2.c * ssl_server2.c * ssl_mail_client.c
The warning was caused because in MSVC some of the function parameters for the socket APIs are int while the fields in struct addrinfo are size_t e.g. possible data loss.
library/net.c
Outdated
@@ -92,6 +92,14 @@ static int wsa_init_done = 0; | |||
|
|||
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ | |||
|
|||
/* Some MS functions want int and MSVC warns if we pass size_t, | |||
* but the standard fucntions use socklen_t, so cast only for MSVC */ | |||
#if defined(_MSC_VER) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a typo here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied that from the development branch, so the typo comes from there. I will fix the typo here but I do not think its worth creating a PR for development and mbed TLS 2.1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I just saw that. Agreed, we can fix the typo in 2.1 and development on other occasions.
@hanno-arm: Fixed the type in |
programs/ssl/ssl_mail_client.c
Outdated
#define read _read | ||
#define write _write | ||
#define read(fd, buf, len) _read( fd, (void *)buf, (unsigned int)len ) | ||
#define write(fd, buf, len) _write( fd, (const void *)buf, (unsigned int)len ) | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add brackets around the arguments to ensure the casts also work as intended if compound expressions are passed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I copied this from the development branch: https://github.com/ARMmbed/mbedtls/blob/development/library/net_sockets.c#L66
@hanno-arm: Added the brackets around the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Casting should be done in specific cases opnly, and not to be used commonly to fix compilation warnings. Personally, I prefer to use casting only when there is no other choice, and do it carefully..
@@ -57,8 +57,10 @@ | |||
#include <unistd.h> | |||
#else | |||
#include <io.h> | |||
#define read _read | |||
#define write _write | |||
#define read(fd, buf, len) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
personally, I think the MACRO checks should be different, to make it more readable(although this is not part of this PR):
#if defined (_MSC_VER)
#else
#endif
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I think I will skip this change for this PR.
#define read _read | ||
#define write _write | ||
#define read(fd, buf, len) \ | ||
_read( fd, (void *)( buf ), (unsigned int)( len ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Theoretically, we could lose data here. parameter len
is size_t
, which is 64 bit in x64. if for some reason, len would be MAX_UINT, we will downcast to unsigned int and lose information. This casting only removes the warning(symptom), not the data loss.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we could. In fact, I copied this code from the development branch: https://github.com/ARMmbed/mbedtls/blob/development/library/net_sockets.c#L67. I do not think this is a major problem as this is only sample code (even the net_sockets.c), but perhaps we could improve the quality of this code. Do you think I should raise an issue on this or fix it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we should raise an issue for this, but if possible, fis it here while we are modifying this file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem in this case is that in Unix we use the function read() while in Windows we use the function _read. Annoyingly the signature for these two functions is different, hence why we use the cast in the Window case as the type of len
in linux is size_t
. We could try to add some checks to make sure that the input parameter is not overflowed as you say, but we would need to use #if
guards and I think that this just complicates the sample code...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at least comment this, so people using this sample code would be aware of this risk
@@ -1791,7 +1791,7 @@ int main( int argc, char *argv[] ) | |||
unsigned char *larger_buf; | |||
|
|||
ori_len = ret; | |||
extra_len = ssl_get_bytes_avail( &ssl ); | |||
extra_len = (int) ssl_get_bytes_avail( &ssl ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to change extra_len
to size_t
type, and thus remove the need for casting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that is a good idea, however everything I have done here is backport the fix from the development branch. Do you think I should try to fix the problem here or raise another issue to address this in all the 3 branches?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think both:)
I think you should fix here, as we are already modifying the file, and raise another issuer for the other two branches
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RonEld: Even if we change this to size_t we will eventually need to cast as the return type of ssl_read()
is int
. In any case, we will not overflow the buffer because according to the RFC 5246 the length of the TLS record's content cannot exceed 2^14.
I'm ok with the conversion inside the test applications. As for the explicit unsigned-to-signed cast in In general, I think we should open an issue on systematically investigating all compiler warnings that we receive when compiling with GCC and |
@@ -1267,7 +1267,7 @@ int main( int argc, char *argv[] ) | |||
|
|||
len = polarssl_snprintf( (char *) buf, sizeof(buf) - 1, GET_REQUEST, | |||
opt.request_page ); | |||
tail_len = strlen( GET_REQUEST_END ); | |||
tail_len = (int) strlen( GET_REQUEST_END ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should consider changing tail_len
to size_t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at the code again and I think that if we change this to size_t we will eventually need to use casts back to int. The problem is that functions such as snprintf()
return int. Also, note that all the input parameters, etc are of type int so its not that straight forward to change one type. I think its best if we just investigate these problems as part of #1007
@andresag01 Would you mind forward-porting the changes in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I approve this, however we should investigate further the need for casting
@RonEld, @hanno-arm: Please note that I have fixed a further compilation warning in x509.c |
@andresag01 please investigate CI failures |
@RonEld I think the CI doesn't work for maintenance branches. Could you check @andresag01 changes from July 31th (added since your last approval) and put the PR to Waiting for Approval state if you're fine? |
@hanno-arm I know the CI doesn't work for CI builds. I don't know why I made that comment... |
Reviewed, tested, approved and merged with |
Threat model summary 2.28
Fix 6 compilation warnings in mbed TLS 1.3 in the sample programs and the net.c module. All the warnings are related to conversions from size_t to int, which can result in a loss of data. The fixes are essentially small backports from the code in the mbed TLS development branch.