Opened 7 years ago

Closed 21 months ago

#53567 closed defect (wontfix)

Signed libraries in app-bundle don't work in MacOS 10.10 after libgcc update

Reported by: michalfapso (Michal Fapso) Owned by:
Priority: Normal Milestone:
Component: ports Version: 2.4.0
Keywords: Cc:
Port: libgcc

Description

What should happen:

Signature of an app-bundle properly running on MacOS 10.12 should be accepted also on MacOS 10.10

What happens

The app-bundle doesn't run on MacOS 10.10. It complains about an invalid signature for libstdc++.6.dylib and libgomp.1.dylib, which were included in the app-bundle/Frameworks subdir. It shows the error only when running the app. Verifying the signature on both MacOS 10.10 and 10.12 using codesign or spctl doesn't show any problem.

Here is the crash report:

Process:               main [2704]
Path:                  /Users/USER/Downloads/codesign_test.app/Contents/MacOS/main
Identifier:            esc.codesign_test
Version:               ???
Code Type:             X86-64 (Native)
Parent Process:        ??? [1]
Responsible:           main [2704]
User ID:               501

Date/Time:             2017-02-14 01:16:29.681 -0800
OS Version:            Mac OS X 10.10 (14A389)
Report Version:        11
Anonymous UUID:        289A82EA-E13C-9F37-E706-539160D5EEAD

Sleep/Wake UUID:       E4E56CBD-BEDD-4B03-AA8F-C22BFEA5AFE7

Time Awake Since Boot: 290000 seconds

Crashed Thread:        0

Exception Type:        EXC_BREAKPOINT (SIGTRAP)
Exception Codes:       0x0000000000000002, 0x0000000000000000

Application Specific Information:
dyld: launch, loading dependent libraries

Dyld Error Message:
  Library not loaded: @executable_path/../Frameworks/libgomp.1.dylib
  Referenced from: /Users/USER/Downloads/codesign_test.app/Contents/MacOS/main
  Reason: no suitable image found.  Did find:
        /Users/esc/Downloads/codesign_test.app/Contents/MacOS/../Frameworks/libgomp.1.dylib: code signature invalid for '/Users/esc/Downloads/codesign_test.app/Contents/MacOS/../Frameworks/libgomp.1.dylib'

        /Users/esc/Downloads/codesign_test.app/Contents/MacOS/../Frameworks/libgomp.1.dylib: code signature invalid for '/Users/esc/Downloads/codesign_test.app/Contents/MacOS/../Frameworks/libgomp.1.dylib'

Binary Images:
    0x7fff5fdf8000 -     0x7fff5fe2e837  dyld (353.2.1) <4696A982-1500-34EC-9777-1EF7A03E2659> /usr/lib/dyld

Model: MacBookPro11,3, BootROM VirtualBox, 4 processors, 4 GHz, 3 GB, SMC 2.3f35
Graphics: Display, PCI, 3 MB
Memory Module: Bank 0/DIMM 0, 2.93 GB, DRAM, 1600 MHz, innotek GmbH, -
Network Service: Ethernet, Ethernet, en0
Serial ATA Device: VBOX HARDDISK, 42.95 GB
Serial ATA Device: VBOX CD-ROM
USB Device: USB Tablet
USB Device: USB Keyboard
Thunderbolt Bus: 

It is similar with libstdc++.6.dylib, but it doesn't complain about an invalid signature, because it finds a valid library in /usr/lib/libstdc++.6.dylib and uses that one instead of the one provided in the bundle. However, the version from macports has several new symbols which are not included in the version on MacOS 10.10 which causes "symbol not found" at runtime.

Quick fix

Taking libgomp.1.dylib and libstdc++.6.dylib from our older bundle created before macports update and putting them into the new app-bundle instead of the ones in the current macports, works correctly on both MacOS 10.12 and 10.10.

How to reproduce

The problem with MacOS 10.10 was first reported by two of our users. We installed the 10.10 in a VirtualBox (https://techsviewer.com/install-mac-os-x-10-10-yosemite-retail-on-virtualbox-with-windows-7-or-windows-8/)

main.cpp:

#include <iostream>

int main()
{
        std::cout << "main() works!" << std::endl;
        return 0;
}

Info.plist:

<?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>NSPrincipalClass</key>
        <string>NSApplication</string>
        <key>CFBundleIconFile</key>
        <string></string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleGetInfoString</key>
        <string>Created by Qt/QMake</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleExecutable</key>
        <string>main</string>
        <key>CFBundleIdentifier</key>
        <string>esc.codesign_test</string>
        <key>NOTE</key>
        <string>This file was generated by Qt/QMake.</string>
</dict>
</plist>

PkgInfo:

APPL????

create_bundle.sh:

#!/bin/bash

BUNDLEID=esc.codesign_test
APPCERT="Developer ID Application: Escape Motions, s.r.o"

EXE=main
rm $EXE
g++ -lgomp -mmacosx-version-min=10.8 -o $EXE main.cpp

APP=codesign_test.app
BUNDLE_PATH="$APP"

TARGET_DIR="$APP/Contents/Frameworks"
function copy_lib
{
        DYLIB=$1
        DYLIB_TARGET_NAME=$2
        DYLIB_OTOOL_PATH=$3
        DYLIB_EXE=$4
        if [ -z "$DYLIB_TARGET_NAME" ]; then
                DYLIB_TARGET_NAME="`basename "$DYLIB"`"
        fi
        if [ -z "$DYLIB_OTOOL_PATH" ]; then
                DYLIB_OTOOL_PATH="$DYLIB"
        fi
        if [ -z "$DYLIB_EXE" ]; then
                DYLIB_EXE="$APP/Contents/MacOS/$EXE"
        fi

        if [[ ! -z "$(echo $DESTDIR | grep final_release_)" || ! -e "$TARGET_DIR/$DYLIB_TARGET_NAME" ]]; then
                cp "$DYLIB" "$TARGET_DIR/$DYLIB_TARGET_NAME"
                chmod +w "$TARGET_DIR/$DYLIB_TARGET_NAME"
                install_name_tool -id @executable_path/../Frameworks/$DYLIB_TARGET_NAME "$TARGET_DIR/$DYLIB_TARGET_NAME"
        fi
        #install_name_tool -change `otool -L "$EXE" | grep "$DYLIB_OTOOL_PATH" | awk '{print $1}'` @executable_path/../Frameworks/"`basename "$DYLIB"`" "$EXE"
        install_name_tool -change "$DYLIB_OTOOL_PATH" @executable_path/../Frameworks/"$DYLIB_TARGET_NAME" "$DYLIB_EXE"
}


rm -r $APP
mkdir -p $APP/Contents/MacOS
cp main $APP/Contents/MacOS/
cp Info.plist $APP/Contents
cp PkgInfo $APP/Contents

sign_timestamp="" # --timestamp=none
sign_force=""

mkdir -p $APP/Contents/Frameworks
copy_lib "/opt/local/lib/libgcc/libstdc++.6.dylib" "" "" ""

# Copying the lib from an older bundle:
#copy_lib "/Applications/Rebelle.app/Contents/Frameworks/libstdc++.6.dylib" "libstdc++.6.dylib" "/opt/local/lib/libgcc/libstdc++.6.dylib" ""
# Copying the lib from current macports:
copy_lib "/opt/local/lib/libgcc/libgcc_s.1.dylib" "" "" ""
copy_lib "/opt/local/lib/libgcc/libgcc_s.1.dylib" "" "" "$TARGET_DIR/libstdc++.6.dylib"

copy_lib "/opt/local/lib/libgcc/libgomp.1.dylib" "" "" ""
# Copying the lib from an older bundle:
#copy_lib "/Applications/Rebelle.app/Contents/Frameworks/libgomp.1.dylib" "" "/opt/local/lib/libgcc/libgomp.1.dylib" ""
# Copying the lib from current macports:
copy_lib "/opt/local/lib/libgcc/libgcc_s.1.dylib" "" "" "$TARGET_DIR/libgomp.1.dylib"

IFS=$'\n'
for file_to_sign in `find "$BUNDLE_PATH/Contents" -name '*.dylib'`; do
        echo "signing $file_to_sign"
        # Note: in case of error about a headerpad, an older version of the problematic library has to be activated in macports: sudo port activate libgcc @5.2.0_0
        codesign --verbose $sign_timestamp $sign_force -s "$APPCERT" -i $BUNDLEID "$file_to_sign"
done

codesign $sign_timestamp -f -s "$APPCERT" -v --verbose "$BUNDLE_PATH"


echo "checking..."
echo
spctl -vvvvv --assess "$BUNDLE_PATH"
echo
codesign --verify --strict=symlinks --verbose=4 "$BUNDLE_PATH"
echo
codesign --display --strict=symlinks --verbose=4 "$BUNDLE_PATH"
echo
spctl -a -t exec -vvvv "$BUNDLE_PATH"
echo
echo "checking...done"


appname="${APP%.app}"
#rm "$appname.zip"
zip -r "$appname.zip" "$APP"

Let me know if you need any more info.

Michal

Change History (6)

comment:1 Changed 7 years ago by mf2k (Frank Schima)

Keywords: codesign signature bundle removed

comment:2 Changed 7 years ago by ryandesign (Ryan Carsten Schmidt)

I don't see how this could be a MacPorts problem. I don't see what we could do about it, since we aren't responsible for the methods Apple uses to create and verify code signatures, nor does MacPorts attempt to codesign the software it installs.

comment:3 Changed 7 years ago by michalfapso (Michal Fapso)

I don't understand it as well. It just works with the libraries from previous version of MacPorts and doesn't work with the current ones. So I thought that maybe some compiler flags were changed for libgcc in MacPorts. Are there any gcc compiler or linker flags that could affect code signing the generated binary?

comment:4 Changed 7 years ago by ryandesign (Ryan Carsten Schmidt)

I don't really know anything about code signing.

Nothing has really changed in MacPorts 2.4 about how ports are built. It's largely the same as 2.3.x.

Nothing major has changed lately in the gcc ports either.

comment:5 Changed 7 years ago by michalfapso (Michal Fapso)

I see. Then you can close this bug for now and I keep using the older libraries. I could also try to post this bug report to Apple, because their codesign verification tool doesn't report any problem, but MacOS still refuses to run the app because of an invalid signature.

comment:6 Changed 21 months ago by cjones051073 (Chris Jones)

Resolution: wontfix
Status: newclosed
Note: See TracTickets for help on using tickets.