The single-file bundler adds additional contents (the apps's dependencies) at the end of the host-binary. This violates the strict consistency checks performed by codesign tool in MAC.
This work item track the effort to make the MAC bundle amenable to signing.
https://github.com/dotnet/core/issues/2811
You will get error message: main executable failed strict validation
If you add --no-strict option in codesign, you will get more detailed error messages:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate: the __LINKEDIT segment does not cover the end of the file (can't be processed) in: /Volumes/Data/temp/HelloDotNet/bin/Release/netcoreapp3.0/osx.10.12-x64/publish/MacOS/HelloDotNet
/Volumes/Data/temp/HelloDotNet/bin/Release/netcoreapp3.0/osx.10.12-x64/publish/MacOS/HelloDotNet: the codesign_allocate helper tool cannot be found or used
Here's an attempt to fixup the __LINKEDIT section to accommodate the SingleFile blob at the end of the file: https://github.com/dotnet/core-setup/compare/master...swaroop-sridhar:mac?expand=1
There are some downsides to doing this fixup:
1) We cannot just fixup the size on disk, we also need to increase the vmsize of __LINKEDIT section (that is, the size as loaded). This means that the entire single-file is loaded by the OS loader when the program starts up.
* In the current scheme of things, this leads to loading all the bundle contents twice, which is wasteful
* When bundle contents are processed directly from disk, I think this scheme can be used more natuarally.
2) With the above change, the __LINKEDIT section is loaded, and the program run successfully. However, the codesign tool is still not happy because it sees that there's no __LINKEDIT data that's referring to the content at the end of the section. Adding a reference to this data involves complex fixup with possible cascading effects for VM-addresses. The fixup for this is rather brittle without support from the native linker.
Any update about when this will be fixed or available in a preview release?
We want to distribute a .NET Core 3.0 (preview6) app on MacOS. Code siging is mandatory.
Is there any workaround to publish a signed .NET Core MacOS application?
@MarcWils Did you find some way to publish signed MacOS application?
@MarcWils @pavelkhrulev
After https://github.com/dotnet/core-setup/pull/8590, I have a better understanding of the file layout; I'll try out another fix for this issue to extend the __LINKEDIT section to cover the single-exe metadata.
@MarcWils Did you find some way to publish signed MacOS application?
No I didn't. We reverted to building a native macOS app.
The MAC codesign tool places several restrictions on the layout
__LINKEDIT segment must be the last one__LINKEDIT segment must cover the end of the file__LINKEDIT segment are used by other linkage commands (ex: symbol/string table, dynamic load information etc) In order to circumvent these restrictions, I implemented a change that:
__LINKEDIT segment to include the bundle-dataThis method has certain limitations:
Here's a change that implements the fix: https://github.com/dotnet/core-setup/compare/master...swaroop-sridhar:macsign?expand=1
The fix is somewhat fragile in the long run, because it relies on the current behavior and checks implemented in codesign tool. It may break if the tool introduces more checks (ex: check that all bytes in the string table are referenced).
The reliable way to generate an image is to use the native tool chain, but this involves substantial support in and beyond the .net core SDK.
CC: @jeffschwMSFT @jkotas
CC: @noahfalk
ok, this is going to block distribution of the app. Not cool.
What is my alternative to start sharing my dotnet 3.1 application with my clients?
What is my alternative to start sharing my dotnet 3.1 application with my clients?
@richardlalancetteyoui You can distribute your app without publishing it as a single-file. The single-file-ness of apps is less important on MAC, sine MAC treats apps as folders.
Oh that's a good point!
How do you package a .net core app if not single file?
I can confirm that, whenever selecting the option to create a single-file, the generated binary cannot be signed.
Is this going to be fixed?
What's the point of having a cross-platform framework if the generated binaries cannot be signed for distribution?
Apple has a variety of restrictions on exactly what needs to happen for signing. Those restrictions change over time and we try to address them for various deployment models. Single-file embedding is a new deployment model that will need new work to deal with additional signing restrictions. This probably won't make .NET 5, but there are a variety of other deployment models that are signable, including the existing self-contained deployment, that will continue to work for .NET 5.
Is there a particular issue that's blocking you from using self-contained deployment on macOS right now?
Single file is much smaller to distribute, which is very helpful for desktop applications running .NET Core (which I understand is not a priority, but it would be nice).
If the main concern is size, you can enable trimming even without enabling single file. There are some single-file specific size improvements, but AFAIK it's not huge for macOS at the moment.
My main concern isn't the size, it's the fact that Apple will not allow the app to run unless it's signed.
Currently, Apple allows only apps to be executed as long when they are downloaded from AppStore or they are identified/signed by identified developers, Otherwise, the app will be blocked from running.
The workaround is to unblock the app from the settings, however, if you don't publish the app as self-contained, you will have to unblock each dll/so file you have in your app.
I'm no Mac notarization expert, but I thought that was what https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_disable-library-validation was for?
That link will disable the validation for the libraries and plug-ins only, it will not disable the app validation.
That entitlement will be really helpful after signing the app to disable validating the dlls/so files if we鈥檙e not publishing a single-file.
Is there a workaround in .NET 5? I'm publishing single file using .NET 5 RC but still get the same error when signing the binary.
Tagging subscribers to this area: @agocke, @vitek-karas
See info in area-owners.md if you want to be subscribed.
Guys. This is a make or break for my team. If this cannot be smoothed out, I might have to go for another ecosystem, and I would hate to have to give away .net core.
I'm going to be using .net core to build command line art processing tools, for our designer workflow and this really needs to get addressed as I will be distributing my tools to mac, windows and maybe linux users.
We do plan to fix this, and it's high priority for .NET 6, unfortunately we just haven't had time to fix it for 5.0. As @swaroop-sridhar mentioned, you can use a macOS app bundle to distribute a multi-file app that appears as a single file to consumers.
Unfortunately, command line apps are one of the tools that do not normally use macOS bundles. Until we can fix this authoring issue, it won't be possible to create single-file command line apps on macOS.
@richardlalancette
I know this is very important when deploying CLI to customers/users, and I tried countless method without any luck. Until one day I thought why not put the effort into providing an easier way for the user to bypass gatekeeper! You can write a "run script" to use spctl to whitelist the files/dylibs in single-file output and then execute the CLI tool. This way, at least, the user can run the tool easily, well, easier.
Oh, this is a risky business @Meowzz95, but nonetheless a good lead. Thank you.
This can't be the final solution though.
I'm using CoreRT for command line tools on macOS. It AOT-compiles to a single binary that can be signed and notarized.
CoreRT is experimental and has a bumpy future, so using it comes with some risk and you might not be able to use it with the latest .Net releases and features. But right now it's the only single-file solution I can use on macOS.
@richardlalancette Agreed that .net team should fix this. But using spctl to whitelist ONLY your application files, don't turn off the gatekeeper and it should be just fine, as least same as user manually trust the binary.
OH I see! I didn't realise specific files could be changed. Well worth a quick research spike :) thank you. @Meowzz95
@richardlalancette HAHA, yes we can label specific files and whitelist them in gatekeeper, I'll show you my solution here.
echo "adding x permission to the program, you may need to enter sudo password or use biometric authentication"
sudo chmod +x YOUR_BINARY_EXEC
echo "adding exceptions to gatekeeper...you may need to enter sudo password or use biometric authentication"
ls | xargs -I {} echo $(pwd)/{}| xargs -I {} spctl --add --label "SOME_LABEL" {}
spctl --enable --label "SOME_LABEL"
echo "launching YOUR APP..."
$(pwd)/YOUR_BINARY_EXEC
This is a very straight forward solution without much consideration on skipping the chomd and spctl on the second run, you can add logic to only run those in the first run so that user does not need to enter the password every time they use the app.
Hope this helps as a workaround for people who are distributing single-file to users
@Meowzz95 Very generous of you to share your results. Thank you!
Related work in mono: https://github.com/mono/mono/issues/17881
Most helpful comment
Any update about when this will be fixed or available in a preview release?
We want to distribute a .NET Core 3.0 (preview6) app on MacOS. Code siging is mandatory.
Is there any workaround to publish a signed .NET Core MacOS application?