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

x/mobile/cmd/gomobile: unsealed contents present in the root directory of an embedded framework #66406

Closed
ianmcfall opened this issue Mar 19, 2024 · 13 comments
Labels
help wanted mobile Android, iOS, and x/mobile NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@ianmcfall
Copy link

Go version

go version go1.21.5 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE='on'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/ian/Library/Caches/go-build'
GOENV='/Users/ian/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/ian/go/pkg/mod'
GONOPROXY='github.com/onlicorp/*'
GONOSUMDB='github.com/onlicorp/*'
GOOS='darwin'
GOPATH='/Users/ian/go'
GOPRIVATE='github.com/onlicorp/*'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/ian/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.darwin-arm64'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/ian/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.darwin-arm64/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.5'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/ian/Developer/onli-3/vault-mobile/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/d3/dzvp6x6s76v407myqn_wmlmh0000gn/T/go-build521929990=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

  1. gomobile init

  2. go get golang.org/x/mobile

  3. Create XCFramework
    gomobile bind -target=macos .

  4. Attempt codesign .framework
    codesign --force --sign "Developer ID Application: Comp (TeamID)" --timestamp --options runtime /path/Vault_mobile.xcframework/macos-arm64_x86_64/Vault_mobile.framework

What did you see happen?

  • Result of code signing framework: unsealed contents present in the root directory of an embedded framework
  • Context: shipping macos app for direct distribution fails to pass any binary/framework that isn't codesigned. The notarytool cli from xcode produces the following (regardless of if the xcframework is signed or not:
### Package Issues
###
Status: Invalid
Archive contains critical validation errors
[[ Safe ]]
• MyApp.app/Contents/MacOS/MyApp
• [ERROR] The signature of the binary is invalid.
• [ERROR] The signature of the binary is invalid.

What did you expect to see?

Expected contents to be sealed in the root directory of an embedded framework.

I realize this might be just an XCode issue, but considering the posts I've read about info.plists and bundling problems with the lastest XCode I figured I'd give it a shot. Any insights appreciated.

@gopherbot gopherbot added the mobile Android, iOS, and x/mobile label Mar 19, 2024
@gopherbot gopherbot added this to the Unreleased milestone Mar 19, 2024
@dr2chase
Copy link
Contributor

@hyangah, any clues?

@hyangah
Copy link
Contributor

hyangah commented Mar 20, 2024

Sorry I have no clue. Does codesign ... --verbose give more hints any chance?
It's possible that the framework bundle doesn't meet recent codesign's expected layout.

@hyangah hyangah added help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Mar 20, 2024
@ianmcfall
Copy link
Author

ianmcfall commented Mar 20, 2024

@hyangah

Sorry I have no clue. Does codesign ... --verbose give more hints any chance? It's possible that the framework bundle doesn't meet recent codesign's expected layout.

Not much that tells me anything. But maybe you it'll inform you. I'm using -vvv for verbosity:

codesign -vvv --deep --strict /MyApp.app
--prepared:/MyApp.app/Contents/Frameworks/Vault_mobile.framework/Versions/Current/.
/MyApp.app/codesign-vault-only 2024-03-19 14-21-12/codesign-vault-only.app: unsealed contents present in the root directory of an embedded framework
In subcomponent: /MyApp.app/Contents/Frameworks/Vault_mobile.framework

@ianmcfall
Copy link
Author

ianmcfall commented Mar 21, 2024

XCFramework file tree, for ref (I've included ios, iossimulator as targets as well):

Vault_mobile.xcframework
├── Info.plist
├── ios-arm64
│   └── Vault_mobile.framework
│       ├── Headers -> Versions/Current/Headers
│       ├── Info.plist
│       ├── Modules -> Versions/Current/Modules
│       ├── Resources -> Versions/Current/Resources
│       ├── Vault_mobile -> Versions/Current/Vault_mobile
│       └── Versions
│           ├── A
│           │   ├── Headers
│           │   │   ├── Universe.objc.h
│           │   │   ├── Vault_mobile.h
│           │   │   ├── Vault_mobile.objc.h
│           │   │   └── ref.h
│           │   ├── Modules
│           │   │   └── module.modulemap
│           │   ├── Resources
│           │   │   └── Info.plist
│           │   └── Vault_mobile
│           └── Current -> A
├── ios-arm64_x86_64-simulator
│   └── Vault_mobile.framework
│       ├── Headers -> Versions/Current/Headers
│       ├── Info.plist
│       ├── Modules -> Versions/Current/Modules
│       ├── Resources -> Versions/Current/Resources
│       ├── Vault_mobile -> Versions/Current/Vault_mobile
│       └── Versions
│           ├── A
│           │   ├── Headers
│           │   │   ├── Universe.objc.h
│           │   │   ├── Vault_mobile.h
│           │   │   ├── Vault_mobile.objc.h
│           │   │   └── ref.h
│           │   ├── Modules
│           │   │   └── module.modulemap
│           │   ├── Resources
│           │   │   └── Info.plist
│           │   └── Vault_mobile
│           └── Current -> A
└── macos-arm64_x86_64
    └── Vault_mobile.framework
        ├── Headers -> Versions/Current/Headers
        ├── Info.plist
        ├── Modules -> Versions/Current/Modules
        ├── Resources -> Versions/Current/Resources
        ├── Vault_mobile -> Versions/Current/Vault_mobile
        └── Versions
            ├── A
            │   ├── Headers
            │   │   ├── Universe.objc.h
            │   │   ├── Vault_mobile.h
            │   │   ├── Vault_mobile.objc.h
            │   │   └── ref.h
            │   ├── Modules
            │   │   └── module.modulemap
            │   ├── Resources
            │   │   └── Info.plist
            │   └── Vault_mobile
            └── Current -> A

34 directories, 28 files

@Simon-Zeng
Copy link

@ianmcfall @hyangah @dr2chase I guess the issue is due to Info.plist under macos-arm64_x86_64/Vault_mobile.framework/, as Apple has pointed out that The framework’s root must contain only the Versions directory and symlinks. Don’t place any other content there. Doing so causes code-signing problems.

Pleases refer: https://developer.apple.com/documentation/bundleresources/placing_content_in_a_bundle

@ianmcfall
Copy link
Author

ianmcfall commented Mar 22, 2024

@Simon-Zeng Good call, thanks! codesign passes when:

  1. gomobile bind -target=macos .
  2. rm .../Vault_mobile.framework/Info.plist -> must explicitly remove Info.plist bc step 1 generates one at the framework root (bind generated file below):
<?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>
      </dict>
    </plist>
  1. Add XCFramework to SPM / Archive App that includes swift package / Distribute / Export & Sign (Xcode flow)
  2. Codesign passes:
codesign -vvv --deep --strict MyApp.app

--prepared:MyApp.app/Contents/Frameworks/Vault_mobile.framework/Versions/Current/.
--validated:MyApp.app/Contents/Frameworks/Vault_mobile.framework/Versions/Current/.
MyApp.app: valid on disk
MyApp.app: satisfies its Designated Requirement

Questions

  • Is there a flag or some config I can pass to gomobile to prevent the extraneous framework root Info.plist from being generated? (Note: file is generated in all target framework root directories)
  • What purpose does it serve, especially when its contents are practically empty?

@Simon-Zeng
Copy link

Simon-Zeng commented Mar 25, 2024

@ianmcfall iOS requires an Info.plist located under framework root when running on Xcode 15.3 and above. So the best solution would be create an alias of Info.plist under framework root from Info.plist under {$framework root}/Versions/Current/Resources/, which will work for both iOS and Mac OS.

@scosman
Copy link

scosman commented Mar 25, 2024

My fix for another issues seems to fix this as well: https://go-review.googlesource.com/c/mobile/+/574055

I can repo a code signing issue before, but not after. Different error message though.

@ianmcfall want to verify?

@Simon-Zeng the suggested symlink will fix this issue, but will cause other issues. Good call on cause!

@gopherbot
Copy link

Change https://go.dev/cl/574055 mentions this issue: cmd/gomobile: produce frameworks which follow Apple's specs per platform, fixing Xcode 15.3 compatibility issues

@ianmcfall
Copy link
Author

Thanks for the help, everyone. Closing.

@ianmcfall
Copy link
Author

ianmcfall commented Mar 25, 2024

My fix for another issues seems to fix this as well: https://go-review.googlesource.com/c/mobile/+/574055

I can repo a code signing issue before, but not after. Different error message though.

@ianmcfall want to verify?

@Simon-Zeng the suggested symlink will fix this issue, but will cause other issues. Good call on cause!

Apologies @scosman, not sure how I can help to verify that update. Might you share what steps I can take to try it out?

@scosman
Copy link

scosman commented Mar 25, 2024

@ianmcfall Steps would be:

  • sync git@github.com:scosman/gomobile.git
  • cd cmd/gomobile
  • go build
  • The run the produced gomobile binary in cmd/gomobile to bind your library, and check it all works

@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Mar 25, 2024
gopherbot pushed a commit to golang/mobile that referenced this issue Mar 26, 2024
…orm, fixing Xcode 15.3 compatibility issues

This patch updates the framework generation code to follow the Apple spec for placing content:
https://developer.apple.com/documentation/bundleresources/placing_content_in_a_bundle

Previously, we setup the framework in MacOS format, and used symlinks to make it compatible with iOS format. This approach no longer works (it works locally in simulator, but causes signing issues when attempting to upload apps for distribution, or running on real hardware). We now setup the expected bundle format for each platform.

Other benefits:

 - Thirds the size of the xcframework and resulting app binary when distributing the xcframework by zip (common for SPM and other formats). The symlinks resulted in duplicate files after zipping, which made it into the final app.
 - Set MinimumOSVersion, fixing SPM compatibility issue
 - Eliminates the blank Info.plist
 - Initial testing shows this also fixes golang/go#66406 (code signing issues) as a side effect of using the proper format

Testing:

 - Tested all 4 platforms (iOS, simulator, macOS, Catalyst) on Xcode 15.3

Fixes golang/go#66406
Fixes golang/go#66500

Change-Id: I8538989efe67cb0d2d0496087dcbeca923c3dffe
GitHub-Last-Rev: 28dca85
GitHub-Pull-Request: #98
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/574055
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Hajime Hoshi <hajimehoshi@gmail.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
hajimehoshi pushed a commit to ebitengine/gomobile that referenced this issue Mar 27, 2024
…orm, fixing Xcode 15.3 compatibility issues

This patch updates the framework generation code to follow the Apple spec for placing content:
https://developer.apple.com/documentation/bundleresources/placing_content_in_a_bundle

Previously, we setup the framework in MacOS format, and used symlinks to make it compatible with iOS format. This approach no longer works (it works locally in simulator, but causes signing issues when attempting to upload apps for distribution, or running on real hardware). We now setup the expected bundle format for each platform.

Other benefits:

 - Thirds the size of the xcframework and resulting app binary when distributing the xcframework by zip (common for SPM and other formats). The symlinks resulted in duplicate files after zipping, which made it into the final app.
 - Set MinimumOSVersion, fixing SPM compatibility issue
 - Eliminates the blank Info.plist
 - Initial testing shows this also fixes golang/go#66406 (code signing issues) as a side effect of using the proper format

Testing:

 - Tested all 4 platforms (iOS, simulator, macOS, Catalyst) on Xcode 15.3

Fixes golang/go#66406
Fixes golang/go#66500

Change-Id: I8538989efe67cb0d2d0496087dcbeca923c3dffe
GitHub-Last-Rev: 28dca85
GitHub-Pull-Request: golang#98
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/574055
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Hajime Hoshi <hajimehoshi@gmail.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
@ianmcfall
Copy link
Author

...and check it all works

@scosman I just confirmed your git@github.com:scosman/gomobile.git passes the codesign checks successfully for a macOS app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted mobile Android, iOS, and x/mobile NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
7 participants