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

macOS Mojave: Support for Hardened Runtime? #4288

Open
wjk opened this issue Jun 18, 2018 · 36 comments

Comments

@wjk
Copy link
Contributor

commented Jun 18, 2018

In macOS Mojave, Apple has introduced support for Hardened Runtime. (This is fully explained somewhere in the WWDC 2018 slides, but I cannot right now find exactly where.) One of the hardening mechanisms is a limitation on JIT techniques. It is still fully possible and supported, but the MAP_JIT flag must be passed to mmap() calls, and a specific entitlement must also be present in the code signature. Would it be possible for, when running on or deploying for macOS Mojave or later, to inject this entitlement automatically (similar to what we do with entitlements required for debugging), and to adjust Mono to use the appropriate flag?

This is currently not that high-priority a task, because use of Hardened Runtime is currently optional (and unsupported on macOS High Sierra and earlier). However, Apple has indicated that it will become mandatory for Developer ID apps in a future macOS update; also, apps that are submitted to Apple to be notarized must have Hardened Runtime enabled, effective immediately. Thanks!

@alexanderkyte

This comment has been minimized.

Copy link
Member

commented Jun 18, 2018

Vital for us is to identify what the performance of this new API is. Our JIT is only just barely better than our AOT backend. It sounds like they're adding a lot of overhead. If it's bad enough, it'll make more sense to do AOT+interp. We should measure before we commit to it.

@chamons

This comment has been minimized.

Copy link
Member

commented Jun 18, 2018

A quick look into this suggests at least two sets of changes will be needed:

  • Mono will need to use that new flag
  • XM will need to enable that entitlement where needed.

I've filed mono/mono#9210 for mono to look into their part. Once that is done, we can look at the entitlement (since we can't test it without the runtime JIt actually working).

Thanks for the Issue!

@chamons chamons added the macOS label Jun 18, 2018

@chamons chamons self-assigned this Jun 18, 2018

@chamons chamons added this to the Future milestone Jun 18, 2018

@chamons

This comment has been minimized.

Copy link
Member

commented Jun 18, 2018

We also have AOT available in XM today, but unless you enable Hybrid we still JIT in places.

Good point about performance. I checked https://asciiwwdc.com/ but I couldn't find the session in question easily.

@wjk

This comment has been minimized.

Copy link
Contributor Author

commented Jun 18, 2018

Found it! It's WWDC 2018 session 702, "Your Apps and the Future of macOS Security." It hasn't yet been transcribed, so that's why searching asciiWWDC found nothing.

Furthermore, as far as I can tell, there should be no performance impact compared to prior macOS versions, assuming mmap() is already being used. It's simply another flag you pass to the syscall alongside MAP_PRIVATE or MAP_ANON. In fact, the symbol is already present in the macOS 10.13 SDK in Xcode 9.4.1.

@chamons

This comment has been minimized.

Copy link
Member

commented Jun 18, 2018

@chamons

This comment has been minimized.

Copy link
Member

commented Aug 1, 2018

While some of this still is in research, I believe the following task list is needed for the hardened runtime support:

After all of that lands, we can look into the notary feature.

@chamons

This comment has been minimized.

Copy link
Member

commented Oct 31, 2018

I've created a "hand-crafted" app by:

  • Having an entitlement with these keys:
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.files.user-selected.read-only</key>
	<true/>
  • Resigning with -o runtime

Which crashes (as expected) on launch. I'm now testing with MAP_JIT enabled mono with:

CODE SIGNING: 23936[ManangedHardTime] vm_map_enter: curprot cannot be write+execute. failing
@chamons

This comment has been minimized.

Copy link
Member

commented Oct 31, 2018

The MAP_JIT patch is in 2018-08, 2018-10, and master.

I tested with the latest package off of 2018-08:

  • With System Mono it works after signing with hardened, as expected
  • With Modern, it fails after as expected, but works if you don't sign with -o runtime

So we are through the test hand crafted stage, we need to add support to msbuild \ IDE for the various entitlements, but users that are comfortable with command line hacking could make it work if they use a sufficiently new mono (master is not on -08+ yet, so it'd be a custom build or system mono).

@xfortin-devolutions

This comment has been minimized.

Copy link

commented Jan 14, 2019

@chamons Where are we on this at this moment for Xamarin.Mac projects? I can see the MAP_JIT flag is done for mono.

@chamons

This comment has been minimized.

Copy link
Member

commented Jan 14, 2019

@xfortin-devolutions We have sufficient infrastructure that you can enable the hardened runtime in your project if you don't mind using a text editor \ signing again by hand.

The following are required:

  • You application must be code signed
  • You have to use xamarin-macios from master or d16-0 branch
  • You have to use a custom entitlement file and add at least the following with a text editor:
  <key>com.apple.security.cs.allow-jit</key>
        <true/>
  • You have to re-run the command we sign the application with, adding -o runtime argument

The work to fully complete finish and complete this is on our backlog. We just have not completed it yet.

@xfortin-devolutions

This comment has been minimized.

Copy link

commented Jan 14, 2019

Thanks for the info. Should be feasible. I'm not sure about using a development version of Xamarin though. Do we have an idea on when those changes will trickle down to a released version?

@chamons

This comment has been minimized.

Copy link
Member

commented Jan 14, 2019

Hardened runtime requires mono changes, as you found, and those are only in the latest bits.

16-0 is in the early stages of preview (we just had the first preview) and I don't have a release date yet to share. I would expect something in the order of months.

chamons added a commit that referenced this issue Feb 22, 2019

@migueldeicaza

This comment has been minimized.

Copy link
Member

commented Mar 13, 2019

The change to use MAP_JIT in Mono regressed a few scenarios:

mono/mono#13445

So we are going to need Mono to surface an API to toggle MAP_JIT on, and the MacOS launcher will need to enable that before launching Mono.

@chamons

This comment has been minimized.

Copy link
Member

commented Mar 14, 2019

I am looking at PRing Miguel's launcher patch, landing when mono/mono#13446 lands.

@chamons

This comment has been minimized.

Copy link
Member

commented Mar 15, 2019

I polished up @migueldeicaza 's patch but I can't PR it until we have a mono that supports that option (all tests fail with Unknown command line option: '--use-map-jit').

Living here for now - https://github.com/chamons/xamarin-macios/pull/new/xm_jit_patch

@DamianMehers

This comment has been minimized.

Copy link

commented Apr 7, 2019

Looks like my app won't make it into the Mac app store so I'd like to get it notorized. I'd be happy to try this out and give feedback prior to it being merged into the main branches.

@chamons

This comment has been minimized.

Copy link
Member

commented Apr 8, 2019

@DamianMehers So the steps are roughly listed here:

#4288 (comment)

Let me break it down in a bit more detail:

  • Enable Code Signing
  • Install Xamarin.Mac from d16-1
    • You can mostly get this working on stable \ d16-0 but it involves more manual steps.
  • Open mac signing build tab and make sure you have an entitlement file listed
  • Open that entitlement and make sure:
  <key>com.apple.security.cs.allow-jit</key>
        <true/>

is added.

  • Open your csproj and in the release section add `true
  • Run your release app and try it out.

You can poke me on https://gitter.im/xamarin/xamarin-macios if you have questions, since you are testing a new feature.

@DanWBR

This comment has been minimized.

Copy link

commented Apr 11, 2019

@chamons my app is built on Windows and I just update the MonoBundle contents of the bundle on each update, how could I notarize it? Thanks in advance.

@wjk

This comment has been minimized.

Copy link
Contributor Author

commented Apr 11, 2019

@DanWBR Notarization must be done from a Mac, so you'll need to copy your finished bundle there. The programs you’ll need are part of the Xcode tools; look at the manpages for altool(1) and stapler(1). Unfortunately, I’ve never notarized an app by hand using these tools, so I can’t tell you how to use them in any more detail. Hope this helps!

@rajivshah3

This comment has been minimized.

Copy link

commented Apr 11, 2019

@DanWBR you can get the standard help that you'd expect from a manpage with xcrun altool -h and xcrun stapler -h. This page is also pretty helpful in describing how to use altool and stapler

@DanWBR

This comment has been minimized.

Copy link

commented Apr 11, 2019

Thanks @wjk and @rajivshah3 I've read the info about altool and stapler, but I'm wondering if I need to create a new Xamarin.Mac project and compile my bundle from scratch, since the procedure in here involves updating the csproj file, assuming that you're creating the bundle from a Xamarin.Mac project in macOS.

If the whole procedure to make my existing app bundle notarizable involves just updating Xamarin.Mac.dll and the info.plist file, then I'm ok with that. On the other hand, if it somehow modifies the MacOS/Launcher.exec file, then I'll be in trouble, I guess.

Two days ago I've tried to upload my app to the Mac App Store but got a lot of errors regarding some native libs which support i386 and shouldn't (including libMonoPosix), etc etc... makes me wonder if a XamMac app can still be distributed in the App Store these days.

@chamons

This comment has been minimized.

Copy link
Member

commented Apr 12, 2019

@DanWBR - XamMac apps, which by definition are 32-bit, can not be distributed on the App Store. Apple is rejecting all 32-bit apps. Full stop.

This documentation may be useful in updating your apps.

@chamons

This comment has been minimized.

Copy link
Member

commented Apr 12, 2019

Folks I created #5896 to more directly talk about the notary support and status. I'll have it updated with status and steps I used shortly.

@chamons

This comment has been minimized.

Copy link
Member

commented Apr 12, 2019

@wjk / @rajivshah3 - See #5896 where I have the invocation I used to test things out. Let me know (on that issue) if you are having any troubles.

@gcadmes

This comment has been minimized.

Copy link

commented Apr 26, 2019

@chamons In an earlier comment you mentioned that after providing the necessary entitlements (sandbox, jit, read-only files) the app crashed on launch, which was 'as expected'.

Is this because it wasn't notarized yet, implying that, once hardened AND notarized, it won't crash. Is that correct? (apologize for the noub question).

@chamons

This comment has been minimized.

Copy link
Member

commented Apr 26, 2019

Correct, I was comparing two builds:

  • Before the MAP_JIT commits
  • After the MAP_JIT commits

Without those change, we should and did crash on launch. With those changes, we were able to launch successfully. It matched my expectations that we needed those changes to opt into the hardened runtime.

The blog post may have some useful information for you if you're just getting started on this topic.

@wvrfish

This comment has been minimized.

Copy link

commented May 7, 2019

@chamons I've started looking at Notarizing our app, so as a first step I tried signing it with the hardened runtime (manually, using codesign --option runtime). I expected it to crash as I haven't specified any entitlements at all, however it seems to run without any issues.

You noted above your test app crashed as expected - any idea why I am not seeing the same behaviour on my end?

Thanks

(It's a Developer ID app, using Xamarin.Mac 5.2.1.16)

@chamons

This comment has been minimized.

Copy link
Member

commented May 14, 2019

I would check activity monitor to confirm you are running under the hardened runtime. Without passing in the entitlements, your option might be ignored?

@gcadmes

This comment has been minimized.

Copy link

commented May 15, 2019

@chamons Regarding my earlier comment about crashing on launch, I forgot to mention the app is not going into the app store. It crashed because I had listed the sandbox entitlement. Once I removed the sandbox entitlement and included the following:

<key>com.apple.security.cs.allow-jit</key>
  <true/>
  <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
  <true/>
	<key>com.apple.security.cs.disable-library-validation</key>
  <true/>
	<key>com.apple.security.cs.disable-executable-page-protection</key>
  <true/>

then notarize and staple the app, it launches successfully.

All done command-line via terminal.
Thank you for your quick reply! Cheers.

@wvrfish

This comment has been minimized.

Copy link

commented May 15, 2019

Similar to @gcadmes above, I was getting launch crashes on the macOS 10.14.5 beta until I added those additional entitlements (wasn't using sandbox anyway)

@DamianMehers

This comment has been minimized.

Copy link

commented Jul 31, 2019

@DamianMehers So the steps are roughly listed here:

#4288 (comment)

Let me break it down in a bit more detail:

  • Enable Code Signing

  • Install Xamarin.Mac from d16-1

    • You can mostly get this working on stable \ d16-0 but it involves more manual steps.
  • Open mac signing build tab and make sure you have an entitlement file listed

  • Open that entitlement and make sure:

  <key>com.apple.security.cs.allow-jit</key>
        <true/>

is added.

  • Open your csproj and in the release section add `true
  • Run your release app and try it out.

You can poke me on https://gitter.im/xamarin/xamarin-macios if you have questions, since you are testing a new feature.

Thanks - I got it working and detailed all the steps here https://damian.fyi/2019/07/30/build-notarize-repeat/ On reflection the title is more negative than intended ... I just spent a day building, submitting to be notarized, being rejected and trying again ... it reminded me of the movie/book "Live, Die, Repeat" AKA "The Edge of Tomorrow" ... but I got it working in the end and thought I'd share my learnings.

@mbmleone

This comment has been minimized.

Copy link

commented Aug 3, 2019

My App keeps crashing on startup after turning "Hardened Runtime" on, even after the App is notarized. Earlier in this topic App crashes were mentioned, but this doesn't seem to be the same.
I tried the suggestions of @gcadmes , but still get the startup crash.
Here is the crashlog that shows what I get:
crashlog.txt
Just to be clear, turning "Hardened Runtime" off makes the crash go away.

Anyone has insight into this crash?
Where the crashes reported here earlier the same?

@chamons

This comment has been minimized.

Copy link
Member

commented Aug 8, 2019

@mbmleone This github issues isn't exactly the best place to ask for help on this. If your application is failing with hardened runtime enabled, you likely need additional entitlements disabling the part you are hitting.

0 com.leonemusicreader.MusicReader5 0x00000001080ffc2a mono_arch_create_sdb_trampoline + 122

Suggests either a JIT or a debugging one is needed.

@prathusingh

This comment has been minimized.

Copy link

commented Aug 14, 2019

@chamons
My app is failing for the same reason as @mbmleone
0 com.leonemusicreader.MusicReader5 0x00000001080ffc2a mono_arch_create_sdb_trampoline + 122

@prathusingh

This comment has been minimized.

Copy link

commented Aug 14, 2019

@mbmleone Did it work for you?

@mbmleone

This comment has been minimized.

Copy link

commented Aug 14, 2019

@chamons @prathusingh The suggestion didn't work for me. I have tried to enable many options in entitlements, but have not yet found any that helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.