conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
8.15k stars 971 forks source link

[question] Do SIP issues in Build helpers on macOS come from conan or not? #10668

Open SpaceIm opened 2 years ago

SpaceIm commented 2 years ago

In conan-center, a common issue on macOS is "all shared" build of autotools based recipes.

What happen:

There are 2 workarounds:

Question: does this DYLD_LIBRATY_PATH reinitialization by SIP come from the way conan calls configure in its autotools helpers or not (it relies on self.run under the hood)? Do you see this issue in the new helper? Is there a functional test for this case?

lasote commented 2 years ago

Hi, the new environment mechanism in develop2 should work just fine for these cases, because all the environment is wrapped in a "bat" or "sh" launcher, then the self.run command is composed like "conanrun.sh && command" so the SIP shouldn't affect. The SIP issues come when calling an executable in a protected location of the operating system, like "bash" but if you activate the environment inside the bash and before calling the command it is ok.

I cant' find a specific test for Autotools and SIP but we are building shared libraries and running the test package (with cmake) in some of them.

SpaceIm commented 2 years ago

Ok, I didn't look at those tests, but I would advice these ones for CMake & autotools:

(*) These tests could ensure that VirtualRunEnv/VirtualBuildEnv context are injected only when it matters (for example in autotools test 1, configure needs VirtualRunEnv, but it doesn't matter at build or installation time). I have to say that I have no idea in the new model how you inject VirtualRunEnv/VirtualBuildEnv for specific commands.

Other comment: for these tests, ensure to not inject paths of shared libs into RPATH of executables, otherwise tests would be biased.

memsharded commented 2 years ago

Some CMake (new toolchain) + shared can be found in:

to not inject paths of shared libs into RPATH of executables

Those tests will do whatever the CMakeToolchain is doing by default, I think they are now not injecting any rpaths

SpaceIm commented 2 years ago

Ok thanks for the link. I think they don't test what I'm talking about.

For example I see:

client.run("install app/0.1@ -o chat:shared=True -o hello:shared=True -g VirtualRunEnv")
command = environment_wrap_command("conanrun", "app", cwd=client.current_folder)

client.run_command(command)

So here you test what we are doing with self.run("app", run_environment=True) in conan v1. But I would like to know if we can inject env vars of VirtualBuildEnv and/or VirtualRunEnv in build helpers (and eventually to specific commands of build helpers), and it they survive to SIP. Basically I have no idea how to achieve those injections looking at the documentation. I would have expected something like:

cmake = CMake()
cmake.configure(VirtualBuildEnv=True) # for example here pkg_check_modules() is used, so we have pkgconf in build_requirements(), but it may have been linked to pkgconf shared, so we need build context env vars at configure time.
cmake.build(VirtualBuildEnv=True) # here we may have another build requirement called at build time through a add_custom_command(), and we don't know whether it is linked or not to a shared lib, so we also want build context env vars.

But it doesn't seem to be that simple.

Those tests will do whatever the CMakeToolchain is doing by default, I think they are now not injecting any rpaths

By default, CMake populates RPATH/RUNPATH/LC_RPATH of shared libs and executables in the build tree with paths of dependencies, then cleanup RPATH during installation. So it's not just about conan.

prince-chrismc commented 2 years ago

@SpaceIm could you take a stab are writing a test to cover this use case you see?

I'd love to see it ❤️

SpaceIm commented 2 years ago

Since I still don't understand how VirtualBuildEnv & VirtualRunEnv interact with new (or old) build helpers, I won't be able to write these tests. I don't even fully understand layout() and its scope/side effects in source(), build(), package() and package_info(), and interaction with tools like replace_in_file etc.

SpaceIm commented 2 years ago

Answering myself:

jcar87 commented 1 month ago

Revisiting this old issue - the short answer is that the SIP issue does not come from Conan - although troubleshooting this is complicated.

The System Integrity protection will "purge" the DYLD_ variables when launching "protected" processes, as per https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/RuntimeProtections/RuntimeProtections.html#//apple_ref/doc/uid/TP40016462-CH3-SW1

As far as I can see, protected processes are in /bin and /usr/bin, affecting programs that are used during the build such as /usr/bin/make and /bin/sh - unsure if it applies to all the executables in those directories, but I'm assuming it does.

The "process tree" will usually look like:

Conan (Python interpreter) invokes a shell -> sources conanbuildenv.sh (which sets DYLD_LIBRARY_PATH) -> invokes CMake -> CMake will see DYLD_LIBRARY_PATH during configure

During "build"

Conan -> shell -> source conanbuildenv -> invoke CMake (cmake --build) or make directly -> make -> make will invoke commands in /bin/sh

For the above, the DYLD_LIBRARY_PATH will be purged if:

What we've been able to observe:

However, what I've observed, and I need to fully confirm this - is that make does not always fork into a shell process - in some cases it appears to launch things directly, which is good (as it bypasses the issue). So most of the cases I've seen, if CMake uses GNU make from homebrew, the issues "go away" (alternatively, one can also invoke the make inside an Xcode installation path, which is also not inside /usr/bin)

Autotools build with "all shared" can be fixed by injecting VirtualRunEnv in build scope if not cross building (I'm not 100% sure, I've tested in a recipe having zlib & openssl as dependencies, and test executable in configure may have found my system installed libs).

This is an entirely different issue altogether - and will also be an issue on Linux We have had reported issues in Conan Center due to this workaround, when the "host" dependency graph contains libraries that happen to be used by tools invoked by autotools (e.g. the compiler itself) - as we are exposing Conan libraries to system executables. In order to avoid that, it's possible to cause the linker to emit -rpath only at configure time, so that the executables can run without LD_LIBRARY_PATH, but Im not fully convinced... https://github.com/conan-io/conan-center-index/pull/24702/files