Fix warning with gcc7 - maximum allocation exceeded #377
No reviewers
Labels
No labels
api-spec
bug
CLA requested
CLA valid
compliance
DO NOT MERGE
duplicate
enhancement
feature branch
good first issue
HEADER FORMATTING ISSUE
help wanted
Information
invalid
Jira status: AWAITING REVIEW
Jira status: CLOSED
Jira status: DONE
Jira status: IN PROGRESS
Jira status: IN REVIEW
Jira status: OPEN
Jira status: REOPENED
Jira status: RESOLVED
mirrored
mirror internally
needs: backports
needs: ci
needs: design review
needs: preceding PR
needs: review
needs: work
notabug
open for community contribution
Product Backlog
question
ready for merge
security
stale
type: bug
type: enhancement
type: question
web pages
wontfix
writing
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-ARMmbed/mbed-crypto!377
Loading…
Reference in a new issue
No description provided.
Delete branch "gcc7-warning-fix"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds additional limits checks on the
ASSERT_ALLOCmacros in the test suite helper functions to remove the warning of an allocation potentially exceeding the maximum object size. eg-Werror=alloc-size-larger-than.The warning is present in GCC 7, and is the reason that the
test_m32_everestcomponent inall.shis failing with theubuntu-18.04docker image.Long explanation of the fix
In the test suite
test_suite_psathere's a test case function ofgenerate_random()which takesintas a parameterbytes_argand assigns it tobytesas asize_t. The parameter comes from the data file so comes in via standard IO so could be at the limit. Within this function, it makes a call to the macroASSERT_ALLOC(), passing that parameterbytes+sizeof(trail), without any boundary checks onbytesunchecked.Within
ASSERT_ALLOCthere is then a call tocallocthat takes a parameter of size assize_t, and passesbytes_arganintinto it.In the Everest m32 test, this is failing with the warning? Why? Well, we've moved from LP64, where
intis 32bits, andsize_tis 64 bits, to ILP32 whereintis 32bits andsize_tis 32 bitsIn LP64, an
int(32 bits) plussizeof(trail)(constant, small), will always be less than the limit of asize_t(64 bits), whilst in ILP32, it could exceed the size of thesize_t(32 bits).And so we get the warning.
I don't understand this change. It doesn't seem right and I don't know what it is supposed to fix.
I don't understand this change. Why would
ASSERT_ALLOCto transform a request to allocateSIZE_MAXbytes into successfully doing nothing? Why wouldASSERT_ALLOCcare about a request to allocateSIZE_MAXbytes? Why wouldn't a request to allocateSIZE_MAXbytes a potential bug of the caller?Preexisting: for some reason, probably a bad merge or side-port from mbedtls to mbed-crypto,
ASSERT_ALLOCis defined twice. If you need to change the macro, please remove one occurrence. Choose which one to make the crypto and tls copies of the file as close as possible.I've described the issue above. The issue is actually in
generate_random(). I could have put a bounds check there, and in hindsight, at the point we receive IO it should always be checked anyway, but I put it before eachcalloc, which is more conservative, and because I was concerned we may get more warnings.Fixed.
Steps to reproduce: the warning appears with GCC 7.4 (but not with 6.4 or 5.4), when compiling for a 32-bit platform such as x86, only with
-O2(not with-O1or-Os), only when UBSan is enabled (-fsanitized=undefined). It appears only in one place in the code, intest_suite_psa_crypto.function, ingenerate_random.The warning is about the last line quoted above.
4294967277 = 2^32 - 19 = 2^32 -
sizeof(trail). Since the warning is only triggered at a high optimization level, I suspect it comes from a pass that's done after inlining, and that it's specific to the branching paths through the conditional statements inside theASSERT_ALLOCand inside the UBSancallocwrapper which tests if the first allocation is 0 bytes. On an architecture wheresize_thas the same size asunsigned int, this happens ifbytes_arg == -sizeof(trail). On an architecture wheresize_tis larger, this never happens.Based on this analysis my proposed fix is to add
before the
ASSERT_ALLOCcalls ingenerate_random. I've confirmed locally that this makes the build pass withgcc-7.4 -m32 -O2 -fsanitize=undefined.I'm open to other approaches. But I still don't see a good argument for “fixing”
ASSERT_ALLOC. The current behavior is the desired behavior. If some test code is calling it with arguments that are out of range, that's a bug in the test code and we should not silence that warning.Regardless of whether this is the right place for the fix, the behavior is not correct. If
length == SIZE_MAX,ASSERT_ALLOCshould mark the test case as failed andASSERT_ALLOC_WEAKshould mark the test case as skipped.This may pacify GCC 7 but it angers GCC 5.
@gilles-peskine-arm - I think your proposal is the better fix, so I'll swap to that. I didn't give this too much thought as it's test code and I just wanted to be rid of yet another distraction, but I think it's better to test the input than add a check at the point of failure.
However - I will say - one of my many concerns with the Docker files (and therefore the CI) is that the GCC version is wrong. We shouldn't care about 5.4, it's ancient and the branch is not maintained. We should be testing with GCC 7 or 8 (as does Mbed OS).
This fix is part of the reason why we can't yet make that jump.
On the topic of GCC versions, I think we should actually test with the oldest version we're willing to support (which is definitely ≤5.4 since that's the version on Ubuntu 16.04 which we still use actively) and with the latest release. But that's a topic for another day.
I've reworked the PR to adopt @gilles-peskine-arm's simpler fix.
If you could review again, thanks.
Raised as bug #385 for tracking. (Which I should have done when I first created this PR).
LGTM
No backports required, as this is for PSA code.
Restarted merge job, as Mbed OS importers should not be looking for
apache-2.0.txtanymore.Merge job failed on Mbed OS with the attestation service not being able to build due to API changes in PSA Crypto. Non-blocking issue unrelated to this PR. Merging.