Monday, 19 November 2018

Mojave vs. GDB

Apple's software development tools are based on LLVM, and Apple don't seem to feel it necessary to keep GCC and friends up to date with changes in the Apple tools or security policies.

GDB has been particularly affected by this. You can see why a tool which is capable of interacting with running programs would have to be treated with caution.

Running under Mojave

Even if you run as root (not recommended, but gets you round the security issue - see below), there are problems. You may experience

BFD: /Users/simon/tmp/so/out_parameters: unknown load command 0x32
BFD: /Users/simon/tmp/so/out_parameters: unknown load command 0x32
"/Users/simon/tmp/so/out_parameters": not in executable format: File format not recognized

This bug report might suggest that the answer is to rebuild your software-under-test with -mmacosx-version-min=10.13, but it seems that that only works if it doesn't use any dynamic libraries, which is hard to arrange under macOS.

That bug report notes that the problem is fixed. Another report applies. You can download a version built with both problems fixed from the Sourceware binutils-gdb git (choose the latest version, if more than one); install with e.g.

sudo tar jxvf gdb-20190304.tar.bz2 -C /opt/gcc-8.1.0
This build
  • can find the information needed to catch exceptions without needing to be started with -readnow,
  • doesn't need you to set startup with shell off in your .gdbinit.

Security

From the security point of view, gdb has to be signed. The process used to be as described here, but with Mojave (macOS 10.14) there are changes.

Create a certificate

  1. Start the Keychain Access application (in /Applications/Utilities)
  2. Select the Keychain Access -> Certificate Assistant -> Create a Certificate... menu
  3. Choose a name for the new certificate (this procedure will use "gdb-cert" as an example)
  4. Set "Identity Type" to "Self Signed Root"
  5. Set "Certificate Type" to "Code Signing"
  6. Activate the "Let me override defaults" option
  7. Click several times on "Continue" until the "Specify a Location For The Certificate" screen appears, then set "Keychain" to "Login"
  8. Click on "Continue" until the certificate is created
  9. Finally, in the "Login" keychain view, double-click on the new certificate, and set "When using this certificate" to "Always Trust" (you may prefer to choose the "Custom" option and allow just "Code Signing").
  10. Right-click on the "System" keychain view and unlock it
  11. Drag the new certificate into the "System" keychain
  12. Exit the Keychain Access application. Mojave required you to restart the computer (or, if feeling brave, sudo killall taskgated), but Catalina appears not to require this (and wasn't running taskgated).

Create an "entitlements" file

The certificate created above says the signed program is to be always trusted, but to do what? This file (save in e.g. gdb.xml, or download) says it's to be trusted to debug.

<?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.cs.debugger</key>
    <true/>
</dict>
</plist>

Signing

You need to specify the certificate, the entitlement, and the program to be signed. Note that it's the actual binary object that's signed, so you can use symbolic links if you want to have gdb on more than one path (e.g., for GNAT CE as well as FSF GCC).

$ codesign                 \
  --force                  \
  --sign gdb-cert          \
  --entitlements gdb.xml   \
  /opt/gcc-8.1.0/bin/gdb

22.xi.18: major edit, add new Security section, link to download binary

17.iii.19: noted extra fixes, there may be more than one download

16.v.20: adopted suggestion to limit signing authority; noted Catalina difference

6 comments:

  1. you can make step 9. a bit more restrictive... trust Code Signing only
    9. Finally, in the "Login" keychain view, double-click on the new certificate, and set "Code Signing" to "Always Trust"

    Also, I didn't have to build GCC or GDB... GDB 8.3 after signed works fine - so just brew install gdb is fine now.

    ReplyDelete
    Replies
    1. gdb-9.1 built from source had to be patched as in PR24069
      (sorry for late reply, (a) wasn't receiving notifications, (b) problem with Safari (c) problem signing in)

      Delete
  2. no matter why i do the same
    Starting program: /Users/jjosburn/temp/a.out
    Unable to find Mach task port for process-id 51698: (os/kern) failure (0x5).
    (please check gdb is codesigned - see taskgated(8))

    ReplyDelete
  3. Could you please explain where to put Entitlements XML file?

    ReplyDelete
  4. Wherever you like .. --entitlements /where/ever/gdb.xml

    ReplyDelete
  5. Thanks for the post.
    I appreciate why Apple require signing, but it can be a pain with FOSS.

    ReplyDelete