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

memcpy on overlapping memory zones when verifying a certificate #6701

Closed
pascal-cuoq opened this issue Nov 30, 2022 · 2 comments
Closed

memcpy on overlapping memory zones when verifying a certificate #6701

pascal-cuoq opened this issue Nov 30, 2022 · 2 comments
Labels
bug component-crypto Crypto primitives and low-level interfaces size-s Estimated task size: small (~2d)

Comments

@pascal-cuoq
Copy link

Summary

When cert-app is invoked with the provided certificate, the function mbedtls_mpi_sub_abs eventually calls memcpy on identical, and thus overlapping, memory zones.

memcpy( X->p + n, A->p + n, ( A->n - n ) * ciL );

Both X and A are pointing to YY, local variable of the function ecp_check_pubkey_sw. The callstack at the time of the invalid memcpy call is:

                  stack: memcpy :: library/bignum.c:964 <-
                         mbedtls_mpi_sub_abs :: library/bignum.c:1007 <-
                         add_sub_mpi :: library/bignum.c:1036 <-
                         mbedtls_mpi_add_mpi :: library/ecp.c:984 <-
                         ecp_modp :: library/ecp.c:1027 <-
                         mbedtls_mpi_mul_mod :: library/ecp.c:2616 <-
                         ecp_check_pubkey_sw :: library/ecp.c:2922 <-
                         mbedtls_ecp_check_pubkey :: library/pkparse.c:485 <-
                         pk_get_ecpubkey :: library/pkparse.c:636 <-
                         mbedtls_pk_parse_subpubkey :: library/x509_crt.c:1237 <-
                         x509_crt_parse_der_core :: library/x509_crt.c:1372 <-
                         mbedtls_x509_crt_parse_der_internal :: library/x509_crt.c:1408 <-
                         mbedtls_x509_crt_parse_der :: library/x509_crt.c:1496 <-
                         mbedtls_x509_crt_parse :: library/x509_crt.c:1541 <-
                         mbedtls_x509_crt_parse_file :: programs/x509/cert_app.c:287 <-
                         main

System information

Mbed TLS version (number or commit id): commit a942b37
Operating system and version: abstract POSIX system with implementation-defined choices of GCC for IA32
Configuration (if not default, please attach mbedtls_config.h):

mbedtls_config.h from the repo.

Compiler and options (if you used a pre-built binary, please indicate how you obtained it): abstract compiler with the implementation-defined choices of GCC targeting IA32.

Expected behavior

The specification of the standard function memcpy says that, unlike memmove, it should never be called on overlapping memory zones.

Actual behavior

memcpy is invoked on identical pointer arguments and a nonzero size (36), therefore the source and destination memory zones overlap.

Steps to reproduce

Invoke cert-app with the commandline mode=file and provide the following certificate as cert.crt:

-----BEGIN CERTIFICATE-----
MIIFBDCCBK6gAwIBAgIQA3dcl4czgOpyESx05xx+6DANBgkqhkiG9w0BAQsFADAb
MRkwFwYDVQQDDBByZWRvY3MyMl9UaVMuY29tMB4XDTIyMTEyNzAwMDAwMFoXDTIz
MDEyNjAwMDAwMFowdTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx
FjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGTAXBgNVBAoTEENsb3VkZmxhcmUsIElu
Yy4xHjAcBgNVBAMTFXNuaS5jbG91ZGZsYXJlc3NsLmNvbTBZMBMGByqGSM49AgEG
CCqGSM49AwEHA0IABLC2SYCX1B5yEHzW09W6GKBbmeDCeF19SKT8ajn3vatLFuNS
d1gS9jPVjKO+U/BI5O3RTIWFmXT9fUez8Ljmi6KjggN1MIIDcTAfBgNVHSMEGDAW
gBSlzjfq67B1DpRniLRF+tkkEIeWHzAdBgNVHQ4EFgQUJIDOCqUEKti9Q8U5Sr8/
dza0jT0wPAYDVR0RBDUwM4ILZGlzY29yZC5jb22CDSouZGlzY29yZC5jb22CFXNu
aS5jbG91ZGZsYXJlc3NsLmNvbTAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYI
KwYBBQUHAwEGCCsGAQUFBwMCMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6Ly9jcmwz
LmRpZ2ljZXJ0LmNvbS9DbG91ZGZsYXJlSW5jRUNDQ0EtMy5jcmwwN6A1oDOGMWh0
dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9DbG91ZGZsYXJlSW5jRUNDQ0EtMy5jcmww
PgYDVR0gBDcwNTAzBgZngQwBAgIwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5k
aWdpY2VydC5jb20vQ1BTMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0
cDovL29jc3AuZGlnaWNlcnQuY29tMEAGCCsGAQUFBzAChjRodHRwOi8vY2FjZXJ0
cy5kaWdpY2VydC5jb20vQ2xvdWRmbGFyZUluY0VDQ0NBLTMuY3J0MAwGA1UdEwEB
/wQCMAAwggF9BgorBgEEAdZ5AgQCBIIBbQSCAWkBZwB2AOg+0No+9QY1MudXKLyJ
a8kD08vREWvs62nhd31tBr1uAAABhI2kUosAAAQDAEcwRQIhAPXXVS3R1NwneuvB
5tHjLystYFlNMdjS8X0WeP07+mtoAiBq64+xNvTNVT63MrJc7WYFg5V1abJS81JN
zYyhzT4ukwB2ALNzdwfhhFD4Y4bWBancEQlKeS2xZwwLh9zwAw55NqWaAAABhI2k
UwEAAAQDAEcwRQIgdezKk7oA0SDKXnUKLLxtVDQl+VocRGo9/vQFoyexYGgCIQCH
vblbEQEgVcfwr3c7g5MJTUyXigLp6pAZ7LlVMyji5QB1ALc++yTfnE26dfI5xbpY
9Gxd/ELPep81xJ4dCYEl7bSZAAABhI2kUr0AAAQDAEYwRAIgKSHr31cDLiIvk4gp
BrYHZQ9C3ihBuguZreR4KorYydMCIBMFYMUMbO/JiLMnMsaEPUQJGT9hTchBvoMc
QZpEoncyMA0GCSqGSIb3DQEBCwUAA0EAF7eqdr95Tm1eFzclAcI79Z37DUll0pQ/
L2RIvRuChCBl4kGPIVy/vZycgXtPaHxT/Px3IJ15YyUsV6SCvn9KYw==
-----END CERTIFICATE-----

Additional information

I follow the development of enough open-source projects to be familiar with the usual reports from well-meaning users of the project who have applied a static analyzer to the source code without being able to do the classification of warnings between false positives and bugs. I would like to emphasize that this is not such a report: the situation I described certainly happens for the provided input.

This bug was found using TrustInSoft Analyzer during the REDOCS'22 event.

@gilles-peskine-arm
Copy link
Contributor

Interestingly, as of Clang 15, Asan yells with a partially overlapping memcpy, but not when the source is equal to the destination. So even though we do have a test case that does have the problematic behavior, the test is passing. Score another point for static analysis.

@gilles-peskine-arm gilles-peskine-arm added bug component-crypto Crypto primitives and low-level interfaces size-s Estimated task size: small (~2d) labels Dec 1, 2022
ucko added a commit to ucko/mbedtls that referenced this issue Jan 17, 2023
In some contexts, the output pointer may equal the first input
pointer, in which case copying is not only superfluous but results in
"Source and destination overlap in memcpy" errors from Valgrind (as I
observed in the context of ecp_double_jac) and a diagnostic message
from TrustInSoft Analyzer (as Pascal Cuoq reported in the context of
other ECP functions called by cert-app with a suitable certificate).

Signed-off-by: Aaron M. Ucko <ucko@ncbi.nlm.nih.gov>
gilles-peskine-arm added a commit that referenced this issue Feb 1, 2023
mbedtls_mpi_sub_abs: Skip memcpy when redundant (#6701).
gilles-peskine-arm pushed a commit that referenced this issue Feb 1, 2023
In some contexts, the output pointer may equal the first input
pointer, in which case copying is not only superfluous but results in
"Source and destination overlap in memcpy" errors from Valgrind (as I
observed in the context of ecp_double_jac) and a diagnostic message
from TrustInSoft Analyzer (as Pascal Cuoq reported in the context of
other ECP functions called by cert-app with a suitable certificate).

Signed-off-by: Aaron M. Ucko <ucko@ncbi.nlm.nih.gov>
gilles-peskine-arm added a commit that referenced this issue Feb 1, 2023
[Backport 2.28] mbedtls_mpi_sub_abs: Skip memcpy when redundant (#6701).
yanrayw pushed a commit to yanrayw/mbedtls that referenced this issue Feb 7, 2023
In some contexts, the output pointer may equal the first input
pointer, in which case copying is not only superfluous but results in
"Source and destination overlap in memcpy" errors from Valgrind (as I
observed in the context of ecp_double_jac) and a diagnostic message
from TrustInSoft Analyzer (as Pascal Cuoq reported in the context of
other ECP functions called by cert-app with a suitable certificate).

Signed-off-by: Aaron M. Ucko <ucko@ncbi.nlm.nih.gov>
@tom-cosgrove-arm
Copy link
Contributor

Duplicate of #4387, and fixed by #6942

paul-elliott-arm pushed a commit to paul-elliott-arm/mbedtls that referenced this issue Feb 14, 2023
In some contexts, the output pointer may equal the first input
pointer, in which case copying is not only superfluous but results in
"Source and destination overlap in memcpy" errors from Valgrind (as I
observed in the context of ecp_double_jac) and a diagnostic message
from TrustInSoft Analyzer (as Pascal Cuoq reported in the context of
other ECP functions called by cert-app with a suitable certificate).

Signed-off-by: Aaron M. Ucko <ucko@ncbi.nlm.nih.gov>
gouriano pushed a commit to ncbi/ncbi-cxx-toolkit-public that referenced this issue May 25, 2023
"Source and destination overlap in memcpy" would normally be a
legitimate cause for concern, but is a harmless formality in this case
because they're consistently identical, as detailed in
Mbed-TLS/mbedtls#6701 (whose fix VDB
evidently doesn't yet bundle).  JIRA: CXX-13024.

git-svn-id: https://anonsvn.ncbi.nlm.nih.gov/repos/v1/trunk/c++@99869 78c7ea69-d796-4a43-9a09-de51944f1b03
lhuang04 pushed a commit to lhuang04/mbedtls that referenced this issue Apr 2, 2024
In some contexts, the output pointer may equal the first input
pointer, in which case copying is not only superfluous but results in
"Source and destination overlap in memcpy" errors from Valgrind (as I
observed in the context of ecp_double_jac) and a diagnostic message
from TrustInSoft Analyzer (as Pascal Cuoq reported in the context of
other ECP functions called by cert-app with a suitable certificate).

Signed-off-by: Aaron M. Ucko <ucko@ncbi.nlm.nih.gov>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug component-crypto Crypto primitives and low-level interfaces size-s Estimated task size: small (~2d)
Projects
None yet
Development

No branches or pull requests

3 participants