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

"cmake -DMBEDTLS_CONFIG_FILE" does not *install* the specified mbedtls_config.h #9947

Open
byron-hawkins opened this issue Feb 2, 2025 · 6 comments
Labels
bug component-platform Portability layer and build scripts help-wanted This issue is not being actively worked on, but PRs welcome.

Comments

@byron-hawkins
Copy link

Summary

In cmake, option -DMBEDTLS_CONFIG_FILE=my_mbedtls_config.h makes that file take the place of include/mbedtls/mbedtls_config.h. However, during cmake install, the override is ignored and the original include/mbedtls/mbedtls_config.h is copied into the build area.

System information

Mbed TLS version (number or commit id): 2ca6c285a0dd3f33982dd57299012dacab1ff206 (though no change is apparent on the default development branch)
Operating system and version: Fedora 41
Configuration (if not default, please attach mbedtls_config.h): (not relevant)
Compiler and options (if you used a pre-built binary, please indicate how you obtained it): (not relevant)
Additional environment information:

Expected behavior

When the user specifies an alternative mbedtls_config.h, it should not only be used in the build, but also be installed. Otherwise the mbedtls_config.h in the installed includes is not consistent with the build it corresponds to.

Actual behavior

cmake copies the original include/mbedtls/mbedtls_config.h instead of the one that was actually used to produce the corresponding build.

Steps to reproduce

Set flag -DMBEDTLS_CONFIG_FILE to any file other than include/mbedtls/mbedtls_config.h and observe that in fact it is the latter file which is installed, not the former.

Additional information

@gilles-peskine-arm
Copy link
Contributor

Good point! But with the added wrinkle that it isn't enough to install the alternative config file. Unless you pass -DMBEDTLS_CONFIG_FILE when compiling any file that includes an mbedtls header, the default config file would still be used.

I'm not sure how to fully resolve this. MBEDTLS_CONFIG_FILE contains a path that's passed to the compiler while building Mbed TLS itself. This can be an absolute path, and often is, to make it easier to build files in subsubdirectories. But after installation, it must not be a relative path.

I wonder what is the right way to resolve this. Inject the setting into the installed mbedtls_config.h? How do we determine the correct post-installation path?

Note that this applies to MBEDTLS_USER_CONFIG_FILE as well. And TF_PSA_CRYPTO_CONFIG_FILE and TF_PSA_CRYPTO_USER_CONFIG_FILE in TF-PSA-Crypto. (In 3.6, we have the CMake variables to change mbedtls_config.h, but for changing crypto_config.h, the options only exist with the C preprocessor, not with CMake as well.)

@gilles-peskine-arm gilles-peskine-arm added component-platform Portability layer and build scripts bug labels Feb 2, 2025
@gilles-peskine-arm
Copy link
Contributor

(I'm not sure whether to label this “bug” or “enhancement”. We mostly intended this for the convenience of developer builds and test scripts, and I guess we just didn't think about usage outside the development team. But once the possibility is there, it is natural to expect it to work together with installation.)

@byron-hawkins
Copy link
Author

To be more specific, here is the use case:

  1. user builds mbedtls with -DMBEDTLS_CONFIG_FILE then make
  2. user installs mbedtls with make install
  3. user copies the installed static libraries and the include/ subtree into some other project A (or imports these as a cmake package, or whatever)
  4. user builds project A, which includes some mbedtls headers from the install, which recursively include the specific file include/mbedtls/mbedtls_config.h, and this configuration absolutely does not match the corresponding binaries

Notice that the user has no option to set -DMBEDTLS_CONFIG_FILE in project A, because there is no such flag in project A. It is some completely other project that is using mbedtls. As a specific example, when I did this after enabling MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK, my static mbedtls libs had the callback enabled. But because the original mbedtls_config.h was installed alongside that static lib, it still had MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK commented out, and my build failed with an undefined symbol on the callback.

This is a bug, not an enhancement request. When cmake builds mbedtls with a certain configuration C, it is imperative that the installed mbedtls_config.h exactly matches the configuration C as it was built. Otherwise dependent projects will absolutely and certainly fail to build.

@gilles-peskine-arm
Copy link
Contributor

When cmake builds mbedtls with a certain configuration C, it is imperative that the installed mbedtls_config.h exactly matches the configuration C as it was built.

This is only the case when you don't pass compiler flags that change the meaning of the header files. And passing -DMBEDTLS_CONFIG_FILE=… to the compiler (i.e. in CFLAGS) changes the meaning of the header files. So would, for example, passing -DMBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK directly in CFLAGS.

If you pass -DMBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK in CFLAGS when compiling Mbed TLS, you must also pass it whenever you compile something that uses Mbed TLS. The same applies if you pass -DMBEDTLS_CONFIG_FILE=… in CFLAGS.

There is also a CMake variable with the name MBEDTLS_CONFIG_FILE. What it does under the hood is to add -DMBEDTLS_CONFIG_FILE=… to CFLAGS, with some CMake magic (I think) to ensure that the file path will be correct relative to the build directory. I'm not sure how that can be communicated after installation.

Using both MBEDTLS_CONFIG_FILE and install in the same build was not specifically intended to work when we added MBEDTLS_CONFIG_FILE as a CMake variable. So it's more like a missing feature, and one that to me looks difficult to implement.

I do agree that the current situation is not good though. But if we don't find a better solution, we may resolve it by throwing an error on make install if MBEDTLS_CONFIG_FILE is defined.

@gilles-peskine-arm gilles-peskine-arm added the help-wanted This issue is not being actively worked on, but PRs welcome. label Feb 2, 2025
@gilles-peskine-arm
Copy link
Contributor

By the way, we don't have a lot of CMake expertise (although we're learning). If you (or anyone) knows how to do this right, we would welcome a patch.

@byron-hawkins
Copy link
Author

What would be the use case for building mbedtls with cmake and not using the install phase of the build? It seems fairly hypothetical.

We're not willing to include mbedtls defines in all downstream projects, so we are simply adding a post-install step to clobber the incompatible mbedtls_config.h with one that matches the binaries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug component-platform Portability layer and build scripts help-wanted This issue is not being actively worked on, but PRs welcome.
Projects
Status: No status
Development

No branches or pull requests

2 participants