Skip to content
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

Conversation

andresag01
Copy link
Contributor

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.

Andres Amaya Garcia added 2 commits July 6, 2017 14:36
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)

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.

Copy link
Contributor Author

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.

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.

@andresag01
Copy link
Contributor Author

@hanno-arm: Fixed the type in library/net.c

#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

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andresag01
Copy link
Contributor Author

@hanno-arm: Added the brackets around the buf and len arguments.

Copy link
Contributor

@RonEld RonEld left a 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) \
Copy link
Contributor

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

Copy link
Contributor Author

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 ) )
Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

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

Copy link
Contributor Author

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...

Copy link
Contributor

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 );
Copy link
Contributor

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

Copy link
Contributor Author

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?

Copy link
Contributor

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

Copy link
Contributor Author

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.

@hanno-becker
Copy link

I'm ok with the conversion inside the test applications. As for the explicit unsigned-to-signed cast in net.c for MSVC, I think we can omit the bounds check there because if the windows API returns an addr_len outside the value range of int, there's already something broken at the OS level (though, admittedly, not broken in the strict sense of a violation of the specification).

In general, I think we should open an issue on systematically investigating all compiler warnings that we receive when compiling with GCC and -Wconversion enabled. This would e.g. also include the issue @RonEld raised about extra_len, because it is later used as part of the third argument to memset, which is expected to be a size_t.

@@ -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 );
Copy link
Contributor

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

Copy link
Contributor Author

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

@hanno-becker
Copy link

@andresag01 Would you mind forward-porting the changes in net.c and ssl_mail_client.c? I think it's best to do it now instead of opening another issue or forgetting about it altogether.

Copy link
Contributor

@RonEld RonEld left a 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

@andresag01
Copy link
Contributor Author

@RonEld: I agree, @hanno-arm has opened a separate issue to look into the casting #1007

@andresag01
Copy link
Contributor Author

@RonEld, @hanno-arm: Please note that I have fixed a further compilation warning in x509.c x509_parse_int() and added a ChangeLog entry.

@RonEld
Copy link
Contributor

RonEld commented Aug 1, 2017

@andresag01 please investigate CI failures

@hanno-becker
Copy link

@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?

@RonEld
Copy link
Contributor

RonEld commented Sep 11, 2017

@hanno-arm I know the CI doesn't work for CI builds. I don't know why I made that comment...
Anyway, I added some comments, but not blocking.

@simonbutcher
Copy link
Contributor

Reviewed, tested, approved and merged with mbedtls-1.3.

paul-elliott-arm pushed a commit that referenced this pull request Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants