openssl: OpenSSL can't see OPENSSL_MODULES env var when using Linux capabilities

Background

OpenSSL, and specifically the libssl part of it, is primarily used for network encryption. In Cloud, it is generally good practice that an application which uses of OpenSSL is NOT running as root. This prevents the application from binding to a privileged network:port (e.g. 443, typically any port < 1024), UNLESS the net-cap-bind-service capability is added to the application (e.g. sudo setcap cap_net_bind_service=+ep /path/to/application) As a result, running an application in Cloud as non-root, but with addition of net-cap-bind-service capabilities, is in widespread use in Cloud.

Issue

Linux capabilities provide a subset of the available root privileges to a process. Given the higher privileges, application programs with added capabilities are therefore started in a secure-execution mode in Linux. For security reasons, if the dynamic linker determines that a binary should be run in secure-execution mode, the effects of some environment variables are voided or modified, and furthermore those environment variables are stripped from the environment, so that the program does not even see the definitions.

This means OpenSSL will not be able to see/read the OPENSSL_MODULES environment variable, and therefore will never load a provider. This renders the providers useless in situations where capabilities are added to applications, specifically the case for net-cap-bind-service capability.

About this issue

  • Original URL
  • State: open
  • Created 10 months ago
  • Comments: 25 (17 by maintainers)

Commits related to this issue

Most upvoted comments

If I understand the problem right, it is not a problem that the environment variables aren’t set. The problem is that the ossl_safe_getenv() treats the process as one with elevated privileges and thus disregards them.

IMO the proposal is OK apart from some minor details. I do not think we need any other tests than a new build added to CI (probably the runchecker CI) that enables this code to be built. As executing with this extra capability bit set would be a problem.

This seems like an administrative problem. The os intentionally removes environment variables, so the solution would seem to me to be creating a shell wrapper around your applicaiton. something like: cat /path/to/application wrapper #!/bin/sh export OPENSSL_MODULES=/path/to/modules exec /path/to/real/application

No?

Agreed, but:

The problems start when providers are not in this directory, and one can’t copy the provider.so to that directory. The latter is the case when there aren’t sufficient access rights to that directory, or when that directory doesn’t exist anymore in the case one only uses the library.so and provider.so files for minimum size.

The same btw is the case for the openssl.cnf file when using OPENSSL_CONF environment variable to specify this file. In that case, the hard coded openssl version -d will point to a potentially wrong location, which can lead to undetected use of a ‘wrong’ config file.

Last-not-least: A provider can offer configuration capabilities via environment variables, for example the OQS OpenSSL provider to adapt code points for interoperability.