diff mbox series

[1/8] hvf: Add hypervisor entitlement to output binaries

Message ID 20201126215017.41156-2-agraf@csgraf.de
State New
Headers show
Series hvf: Implement Apple Silicon Support | expand

Commit Message

Alexander Graf Nov. 26, 2020, 9:50 p.m. UTC
In macOS 11, QEMU only gets access to Hypervisor.framework if it has the
respective entitlement. Add an entitlement template and automatically self
sign and apply the entitlement in the build.

Signed-off-by: Alexander Graf <agraf@csgraf.de>
---
 accel/hvf/entitlements.plist |  8 ++++++++
 meson.build                  | 30 ++++++++++++++++++++++++++----
 scripts/entitlement.sh       | 11 +++++++++++
 3 files changed, 45 insertions(+), 4 deletions(-)
 create mode 100644 accel/hvf/entitlements.plist
 create mode 100755 scripts/entitlement.sh

Comments

Paolo Bonzini Nov. 27, 2020, 4:54 a.m. UTC | #1
On 26/11/20 22:50, Alexander Graf wrote:
> +rm -f "$2"
> +cp -a "$SRC" "$DST"
> +codesign --entitlements "$ENTITLEMENT" --force -s - "$DST"

Slight improvement to avoid races between ^C and this script:

set -e
trap 'rm "$DST.tmp"' exit
cp -a "$SRC" "$DST.tmp"
codesign --entitlements "$ENTITLEMENT" --force -s - "$DST.tmp"
mv "$DST.tmp" "$DST"
trap '' exit

Paolo
Roman Bolshakov Nov. 27, 2020, 7:44 p.m. UTC | #2
On Thu, Nov 26, 2020 at 10:50:10PM +0100, Alexander Graf wrote:
> In macOS 11, QEMU only gets access to Hypervisor.framework if it has the
> respective entitlement. Add an entitlement template and automatically self
> sign and apply the entitlement in the build.
> 
> Signed-off-by: Alexander Graf <agraf@csgraf.de>
> ---
>  accel/hvf/entitlements.plist |  8 ++++++++
>  meson.build                  | 30 ++++++++++++++++++++++++++----
>  scripts/entitlement.sh       | 11 +++++++++++
>  3 files changed, 45 insertions(+), 4 deletions(-)
>  create mode 100644 accel/hvf/entitlements.plist
>  create mode 100755 scripts/entitlement.sh

Hi,

I think the patch should go ahead of other changes (with Paolo's fix for
^C) and land into 5.2 because entitlements are needed for x86_64 hvf too
since Big Sur Beta 3. Ad-hoc signing is very convenient for development.

Also, It might be good to have configure/meson option to disable signing
at all. Primarily for homebrew:

https://discourse.brew.sh/t/code-signing-installed-executables/2131/10

There's no established process how to deal with it, e.g. GDB in homebrew
has caveats section for now:

  ==> Caveats
  gdb requires special privileges to access Mach ports.
  You will need to codesign the binary. For instructions, see:

    https://sourceware.org/gdb/wiki/BuildingOnDarwin

The discussion on discourse mentions some plans to do signing in
homebrew CI (with real Developer ID) but none of them are implemented
now.

For now it'd be helpful to provide a way to disable signing and install
the entitlements (if one wants to sign after installation). Similar
issue was raised to fish-shell a while ago:

https://github.com/fish-shell/fish-shell/issues/6952
https://github.com/fish-shell/fish-shell/issues/7467

> 
> diff --git a/accel/hvf/entitlements.plist b/accel/hvf/entitlements.plist
> new file mode 100644
> index 0000000000..154f3308ef
> --- /dev/null
> +++ b/accel/hvf/entitlements.plist
> @@ -0,0 +1,8 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
> +<plist version="1.0">
> +<dict>
> +    <key>com.apple.security.hypervisor</key>
> +    <true/>
> +</dict>
> +</plist>
> diff --git a/meson.build b/meson.build
> index 5062407c70..2a7ff5560c 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1844,9 +1844,14 @@ foreach target : target_dirs
>      }]
>    endif
>    foreach exe: execs
> -    emulators += {exe['name']:
> -         executable(exe['name'], exe['sources'],
> -               install: true,
> +    exe_name = exe['name']
> +    exe_sign = 'CONFIG_HVF' in config_target

I don't have Apple Silicon HW but it may require different kind of
entitlements for CONFIG_TCG:

https://developer.apple.com/documentation/apple_silicon/porting_just-in-time_compilers_to_apple_silicon

Thanks,
Roman

> +    if exe_sign
> +      exe_name += '-unsigned'
> +    endif
> +
> +    emulator = executable(exe_name, exe['sources'],
> +               install: not exe_sign,
>                 c_args: c_args,
>                 dependencies: arch_deps + deps + exe['dependencies'],
>                 objects: lib.extract_all_objects(recursive: true),
> @@ -1854,7 +1859,24 @@ foreach target : target_dirs
>                 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
>                 link_args: link_args,
>                 gui_app: exe['gui'])
> -    }
> +
> +    if exe_sign
> +      exe_full = meson.current_build_dir() / exe['name']
> +      emulators += {exe['name'] : custom_target(exe['name'],
> +                   install: true,
> +                   install_dir: get_option('bindir'),
> +                   depends: emulator,
> +                   output: exe['name'],
> +                   command: [
> +                     meson.current_source_dir() / 'scripts/entitlement.sh',
> +                     meson.current_build_dir() / exe['name'] + '-unsigned',
> +                     meson.current_build_dir() / exe['name'],
> +                     meson.current_source_dir() / 'accel/hvf/entitlements.plist'
> +                   ])
> +      }
> +    else
> +      emulators += {exe['name']: emulator}
> +    endif
>  
>      if 'CONFIG_TRACE_SYSTEMTAP' in config_host
>        foreach stp: [
> diff --git a/scripts/entitlement.sh b/scripts/entitlement.sh
> new file mode 100755
> index 0000000000..7ed9590bf9
> --- /dev/null
> +++ b/scripts/entitlement.sh
> @@ -0,0 +1,11 @@
> +#!/bin/sh -e
> +#
> +# Helper script for the build process to apply entitlements
> +
> +SRC="$1"
> +DST="$2"
> +ENTITLEMENT="$3"
> +
> +rm -f "$2"
> +cp -a "$SRC" "$DST"
> +codesign --entitlements "$ENTITLEMENT" --force -s - "$DST"
> -- 
> 2.24.3 (Apple Git-128)
> 
>
Paolo Bonzini Nov. 27, 2020, 9:17 p.m. UTC | #3
Il ven 27 nov 2020, 20:44 Roman Bolshakov <r.bolshakov@yadro.com> ha
scritto:

> On Thu, Nov 26, 2020 at 10:50:10PM +0100, Alexander Graf wrote:
> > In macOS 11, QEMU only gets access to Hypervisor.framework if it has the
> > respective entitlement. Add an entitlement template and automatically
> self
> > sign and apply the entitlement in the build.
> >
> > Signed-off-by: Alexander Graf <agraf@csgraf.de>
> > ---
> >  accel/hvf/entitlements.plist |  8 ++++++++
> >  meson.build                  | 30 ++++++++++++++++++++++++++----
> >  scripts/entitlement.sh       | 11 +++++++++++
> >  3 files changed, 45 insertions(+), 4 deletions(-)
> >  create mode 100644 accel/hvf/entitlements.plist
> >  create mode 100755 scripts/entitlement.sh
>
> Hi,
>
> I think the patch should go ahead of other changes (with Paolo's fix for
> ^C) and land into 5.2 because entitlements are needed for x86_64 hvf too
> since Big Sur Beta 3. Ad-hoc signing is very convenient for development.
>

It's certainly too late for 5.2, but we could include the patch in the
release notes and in 5.2.1.

Paolo

Also, It might be good to have configure/meson option to disable signing
> at all. Primarily for homebrew:
>
> https://discourse.brew.sh/t/code-signing-installed-executables/2131/10
>
> There's no established process how to deal with it, e.g. GDB in homebrew
> has caveats section for now:
>
>   ==> Caveats
>   gdb requires special privileges to access Mach ports.
>   You will need to codesign the binary. For instructions, see:
>
>     https://sourceware.org/gdb/wiki/BuildingOnDarwin
>
> The discussion on discourse mentions some plans to do signing in
> homebrew CI (with real Developer ID) but none of them are implemented
> now.
>
> For now it'd be helpful to provide a way to disable signing and install
> the entitlements (if one wants to sign after installation). Similar
> issue was raised to fish-shell a while ago:
>
> https://github.com/fish-shell/fish-shell/issues/6952
> https://github.com/fish-shell/fish-shell/issues/7467
>
> >
> > diff --git a/accel/hvf/entitlements.plist b/accel/hvf/entitlements.plist
> > new file mode 100644
> > index 0000000000..154f3308ef
> > --- /dev/null
> > +++ b/accel/hvf/entitlements.plist
> > @@ -0,0 +1,8 @@
> > +<?xml version="1.0" encoding="UTF-8"?>
> > +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "
> http://www.apple.com/DTDs/PropertyList-1.0.dtd">
> > +<plist version="1.0">
> > +<dict>
> > +    <key>com.apple.security.hypervisor</key>
> > +    <true/>
> > +</dict>
> > +</plist>
> > diff --git a/meson.build b/meson.build
> > index 5062407c70..2a7ff5560c 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -1844,9 +1844,14 @@ foreach target : target_dirs
> >      }]
> >    endif
> >    foreach exe: execs
> > -    emulators += {exe['name']:
> > -         executable(exe['name'], exe['sources'],
> > -               install: true,
> > +    exe_name = exe['name']
> > +    exe_sign = 'CONFIG_HVF' in config_target
>
> I don't have Apple Silicon HW but it may require different kind of
> entitlements for CONFIG_TCG:
>
>
> https://developer.apple.com/documentation/apple_silicon/porting_just-in-time_compilers_to_apple_silicon
>
> Thanks,
> Roman
>
> > +    if exe_sign
> > +      exe_name += '-unsigned'
> > +    endif
> > +
> > +    emulator = executable(exe_name, exe['sources'],
> > +               install: not exe_sign,
> >                 c_args: c_args,
> >                 dependencies: arch_deps + deps + exe['dependencies'],
> >                 objects: lib.extract_all_objects(recursive: true),
> > @@ -1854,7 +1859,24 @@ foreach target : target_dirs
> >                 link_depends: [block_syms, qemu_syms] +
> exe.get('link_depends', []),
> >                 link_args: link_args,
> >                 gui_app: exe['gui'])
> > -    }
> > +
> > +    if exe_sign
> > +      exe_full = meson.current_build_dir() / exe['name']
> > +      emulators += {exe['name'] : custom_target(exe['name'],
> > +                   install: true,
> > +                   install_dir: get_option('bindir'),
> > +                   depends: emulator,
> > +                   output: exe['name'],
> > +                   command: [
> > +                     meson.current_source_dir() /
> 'scripts/entitlement.sh',
> > +                     meson.current_build_dir() / exe['name'] +
> '-unsigned',
> > +                     meson.current_build_dir() / exe['name'],
> > +                     meson.current_source_dir() /
> 'accel/hvf/entitlements.plist'
> > +                   ])
> > +      }
> > +    else
> > +      emulators += {exe['name']: emulator}
> > +    endif
> >
> >      if 'CONFIG_TRACE_SYSTEMTAP' in config_host
> >        foreach stp: [
> > diff --git a/scripts/entitlement.sh b/scripts/entitlement.sh
> > new file mode 100755
> > index 0000000000..7ed9590bf9
> > --- /dev/null
> > +++ b/scripts/entitlement.sh
> > @@ -0,0 +1,11 @@
> > +#!/bin/sh -e
> > +#
> > +# Helper script for the build process to apply entitlements
> > +
> > +SRC="$1"
> > +DST="$2"
> > +ENTITLEMENT="$3"
> > +
> > +rm -f "$2"
> > +cp -a "$SRC" "$DST"
> > +codesign --entitlements "$ENTITLEMENT" --force -s - "$DST"
> > --
> > 2.24.3 (Apple Git-128)
> >
> >
>
>
Alexander Graf Nov. 27, 2020, 9:51 p.m. UTC | #4
On 27.11.20 20:44, Roman Bolshakov wrote:
> On Thu, Nov 26, 2020 at 10:50:10PM +0100, Alexander Graf wrote:
>> In macOS 11, QEMU only gets access to Hypervisor.framework if it has the
>> respective entitlement. Add an entitlement template and automatically self
>> sign and apply the entitlement in the build.
>>
>> Signed-off-by: Alexander Graf <agraf@csgraf.de>
>> ---
>>   accel/hvf/entitlements.plist |  8 ++++++++
>>   meson.build                  | 30 ++++++++++++++++++++++++++----
>>   scripts/entitlement.sh       | 11 +++++++++++
>>   3 files changed, 45 insertions(+), 4 deletions(-)
>>   create mode 100644 accel/hvf/entitlements.plist
>>   create mode 100755 scripts/entitlement.sh
> Hi,
>
> I think the patch should go ahead of other changes (with Paolo's fix for
> ^C) and land into 5.2 because entitlements are needed for x86_64 hvf too
> since Big Sur Beta 3. Ad-hoc signing is very convenient for development.
>
> Also, It might be good to have configure/meson option to disable signing
> at all. Primarily for homebrew:
>
> https://discourse.brew.sh/t/code-signing-installed-executables/2131/10
>
> There's no established process how to deal with it, e.g. GDB in homebrew
> has caveats section for now:
>
>    ==> Caveats
>    gdb requires special privileges to access Mach ports.
>    You will need to codesign the binary. For instructions, see:
>
>      https://sourceware.org/gdb/wiki/BuildingOnDarwin
>
> The discussion on discourse mentions some plans to do signing in
> homebrew CI (with real Developer ID) but none of them are implemented
> now.
>
> For now it'd be helpful to provide a way to disable signing and install
> the entitlements (if one wants to sign after installation). Similar
> issue was raised to fish-shell a while ago:
>
> https://github.com/fish-shell/fish-shell/issues/6952
> https://github.com/fish-shell/fish-shell/issues/7467


All binaries are signed in Big Sur by the linker as far as I understand, 
so I don't quite see the point in not signing :). If the build system 
doesn't have access to codesign, it sounds to me like one should fix the 
build system instead? Worst case by injecting a fake codesign binary 
that just calls /bin/true.


>
>> diff --git a/accel/hvf/entitlements.plist b/accel/hvf/entitlements.plist
>> new file mode 100644
>> index 0000000000..154f3308ef
>> --- /dev/null
>> +++ b/accel/hvf/entitlements.plist
>> @@ -0,0 +1,8 @@
>> +<?xml version="1.0" encoding="UTF-8"?>
>> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
>> +<plist version="1.0">
>> +<dict>
>> +    <key>com.apple.security.hypervisor</key>
>> +    <true/>
>> +</dict>
>> +</plist>
>> diff --git a/meson.build b/meson.build
>> index 5062407c70..2a7ff5560c 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -1844,9 +1844,14 @@ foreach target : target_dirs
>>       }]
>>     endif
>>     foreach exe: execs
>> -    emulators += {exe['name']:
>> -         executable(exe['name'], exe['sources'],
>> -               install: true,
>> +    exe_name = exe['name']
>> +    exe_sign = 'CONFIG_HVF' in config_target
> I don't have Apple Silicon HW but it may require different kind of
> entitlements for CONFIG_TCG:
>
> https://developer.apple.com/documentation/apple_silicon/porting_just-in-time_compilers_to_apple_silicon


You only need the JIT entitlement for the App Store. Locally signed 
applications work just fine without. I don't know about binaries you 
download from the internet that were signed with a developer key though.

Keep in mind that for this to work you also need the MAP_JIT and RWX 
toggle changes from another patch set on the ML.


Alex
diff mbox series

Patch

diff --git a/accel/hvf/entitlements.plist b/accel/hvf/entitlements.plist
new file mode 100644
index 0000000000..154f3308ef
--- /dev/null
+++ b/accel/hvf/entitlements.plist
@@ -0,0 +1,8 @@ 
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>com.apple.security.hypervisor</key>
+    <true/>
+</dict>
+</plist>
diff --git a/meson.build b/meson.build
index 5062407c70..2a7ff5560c 100644
--- a/meson.build
+++ b/meson.build
@@ -1844,9 +1844,14 @@  foreach target : target_dirs
     }]
   endif
   foreach exe: execs
-    emulators += {exe['name']:
-         executable(exe['name'], exe['sources'],
-               install: true,
+    exe_name = exe['name']
+    exe_sign = 'CONFIG_HVF' in config_target
+    if exe_sign
+      exe_name += '-unsigned'
+    endif
+
+    emulator = executable(exe_name, exe['sources'],
+               install: not exe_sign,
                c_args: c_args,
                dependencies: arch_deps + deps + exe['dependencies'],
                objects: lib.extract_all_objects(recursive: true),
@@ -1854,7 +1859,24 @@  foreach target : target_dirs
                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
                link_args: link_args,
                gui_app: exe['gui'])
-    }
+
+    if exe_sign
+      exe_full = meson.current_build_dir() / exe['name']
+      emulators += {exe['name'] : custom_target(exe['name'],
+                   install: true,
+                   install_dir: get_option('bindir'),
+                   depends: emulator,
+                   output: exe['name'],
+                   command: [
+                     meson.current_source_dir() / 'scripts/entitlement.sh',
+                     meson.current_build_dir() / exe['name'] + '-unsigned',
+                     meson.current_build_dir() / exe['name'],
+                     meson.current_source_dir() / 'accel/hvf/entitlements.plist'
+                   ])
+      }
+    else
+      emulators += {exe['name']: emulator}
+    endif
 
     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
       foreach stp: [
diff --git a/scripts/entitlement.sh b/scripts/entitlement.sh
new file mode 100755
index 0000000000..7ed9590bf9
--- /dev/null
+++ b/scripts/entitlement.sh
@@ -0,0 +1,11 @@ 
+#!/bin/sh -e
+#
+# Helper script for the build process to apply entitlements
+
+SRC="$1"
+DST="$2"
+ENTITLEMENT="$3"
+
+rm -f "$2"
+cp -a "$SRC" "$DST"
+codesign --entitlements "$ENTITLEMENT" --force -s - "$DST"