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

Remove dependency on VC runtime library #614

Closed
IgorMilavec opened this issue Oct 16, 2017 · 7 comments
Closed

Remove dependency on VC runtime library #614

IgorMilavec opened this issue Oct 16, 2017 · 7 comments
Labels

Comments

@IgorMilavec
Copy link

Windows binary is currently dependent on Visual C++ runtime library. This affects deployment of libsodium to containers (additional install slows down the build process) and Windows Nano server (which has no installer support).
I propose to link Windows binary with static runtime library instead. This would increase the x64 libsodium.dll size from 283KB to 363KB (tested with VS 2017). Besides simplifying the deployment process, I believe this would also theoretically improve the security by not depending on external code.

I can provide a PR if this is accepted.

@jedisct1
Copy link
Owner

Any opinion on this, @ektrah @BurningEnlightenment @evoskuil ?

@ektrah
Copy link
Contributor

ektrah commented Oct 17, 2017

The manual installation of the VC++ redistributable is indeed a bit annoying. As far as I know, Windows 10 comes with a "Universal CRT" that replaces the need for installing the redistributable and, unlike a statically linked copy, is kept up to date by Windows Update. It might be worth investigating that.

@evoskuil
Copy link
Contributor

Static linkage of MSVCRT for a dynamic link library is not advisable. There is shared state in the runtime that becomes isolated to the DLL. It can appear to work (despite warnings) but can produce insidious failures when other DLLs (or and executable) are linked with either independently-linked copies or (correctly) a dynamically-linked copy.

@IgorMilavec
Copy link
Author

@evoskuil, do you have any reference to static linkage not being advisable? I understand that there could be consequences in accessing shared state with different runtime versions, but IMO libsodium has a cleanly defined interface that does not allow/encourage this?

@ektrah, I will try to link libsodium with Universal C Runtime and test in a container.

@jedisct1
Copy link
Owner

Just wanted to say a big thank you to all of you for your invaluable help with making libsodium easier to use with Visual Studio!

@evoskuil
Copy link
Contributor

It is not that static linkage is a problem, but that static linkage in a dynamic library is a problem. When this occurs you will typically end up with at least two instances of the runtime (not two versions, assuming each inclusion is of the correct version for the compiler). Determining whether it is safe in practice requires openening the black box, which may not only be difficult but would introduce fragility.

This comment doesn't fully describe the limitation, but as you can see if static linkage in the DLL was used, all other DLLs linked to the final EXE must do this as well. That implies two versions of each DLL must be available and the correct one chosen to link with any other depending on how the other was linked (which is not what you will find anywhere).

All modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option (/MD, /MT, /LD).

Also:

Because a DLL built by linking to a static CRT will have its own CRT state, it is not recommended to link statically to the CRT in a DLL unless the consequences of this are specifically desired and understood...

What problems exist if an application uses more than one CRT version?

If you have more than one DLL or EXE, then you may have more than one CRT, whether or not you are using different versions of Visual C++. For example, statically linking the CRT into multiple DLLs can present the same problem. Developers encountering this problem with static CRTs have been instructed to compile with /MD to use the CRT DLL. If your DLLs pass CRT resources across the DLL boundary, you may encounter issues with mismatched CRTs and need to recompile your project with Visual C++.

If your program is using more than one version of the CRT, some care is needed when passing certain CRT objects (such as file handles, locales and environment variables) across DLL boundaries. For more information on the issues involved and how to resolve them, see Potential Errors Passing CRT Objects Across DLL Boundaries.

IMO this is definitely not a road you would want to go down. The VS template that is used in libsodium is specifically designed to ensure that CRT linkage is correct.

@IgorMilavec
Copy link
Author

I agree that statically linking CRT to libsodium could present some interesting challenges for users of the library.
I did some research on the Universal C Runtime and discovered that binaries that you distribute in libsodium-1.0.15-msvc for x64 v140 and v141 already use Universal C Runtime. This means that any application that uses libsodium v140 and is linked to any version of Universal C Runtime, only gets one instance of the runtime.
Universal C Runtime also simplifies deployment scenarios on newer versions of Windows, because you only need to redistribute vcredist140.dll with your app, which is small enough to be deployed side-by-side. Users of Windows Vista, 7 and 8.x will need to install Universal C Runtime.
This basically solved my Windows Nano deployment problems. However, it might be worthwhile to also test deployment onto Windows for IoT. Does anybody have an option to test that?

Repository owner locked and limited conversation to collaborators Aug 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants