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

LD_RUNPATH_SEARCH_PATHS set on macOS target for Cocoapods 1.11.0 fail XProtectService check on Mojave #10954

Open
1 task done
tylerccarson opened this issue Sep 17, 2021 · 6 comments · May be fixed by #11837
Open
1 task done
Milestone

Comments

@tylerccarson
Copy link

tylerccarson commented Sep 17, 2021

Report

What did you do?

Upgraded Cocoapods from 1.10.2 to 1.11.0.

What did you expect to happen?

LD_RUNPATH_SEARCH_PATHS in the xconfig generated by pod install does not contain rpaths outside the main executable.

From the xconfig generated by pod install:

LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks'

What happened instead?

LD_RUNPATH_SEARCH_PATHS have references outside the bundle, which prevents the application from opening on Mojave.

From the xconfig generated by pod install:

LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/../Frameworks' '@loader_path/Frameworks' "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"

I've traced the change to this pull request. The connection between reported objective of this PR and this particular change isn't quite clear to me.

When I try launching the executable, I get the following error from the XProtectService process via the Console.app:

File /Applications/<APPNAME>.app/Contents/PlugIns/<APPEXNAME>.appex/Contents/MacOS/<APPEXNAME> failed on rPathCmd /Applications/Xcode_12.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/CocoaLumberjack.framework/Versions/A/CocoaLumberjack

A couple important notes:

  1. XProtectService doesn't seem to interfere on Catalina and Big Sur, only on Mojave (and presumably lower)
  2. This only happens for Developer ID signed/notorized apps. The Mac App Store signed version doesn't have this issue.

Here's a similar issue that was solved by removing rpath references outside the bundle.

CocoaPods Environment

   CocoaPods : 1.11.2
        Ruby : ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin20]
    RubyGems : 3.0.3
        Host : macOS 11.6 (20G165)
       Xcode : 12.5.1 (12E507)
         Git : git version 2.30.1 (Apple Git-130)
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib
Repositories : trunk - CDN - https://cdn.cocoapods.org/

Project that demonstrates the issue

This configuration output should be reproducible with any macOS project, as long as your Cocoapods version is >= 1.11.0

@dnkoutso
Copy link
Contributor

Thanks for the great issue report! Should we not be adding those for macOS projects?

@dnkoutso dnkoutso added this to the 1.11.3 milestone Sep 17, 2021
@tylerccarson
Copy link
Author

tylerccarson commented Sep 17, 2021

Thanks, it was a team effort connecting all the dots of what was causing this.

My opinion would be no-- we should not add rpath references for outside the bundle, at least not by default. Especially something that is a reference to the Xcode Swift toolchain ("${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}", /usr/lib/swift), since you can't count on it in a production environment. That's something maybe a user should only be manually adding to a Debug build configuration.

@dnkoutso
Copy link
Contributor

The PR you linked allows to build and run app specs or test specs that do not contain Swift but their libraries do. Having a .swift file in a target causes Xcode to copy a bunch of stuff. Its possible we can limit this only to app specs and test specs...

are you using app specs for a macOS target?

@tylerccarson
Copy link
Author

I figured there must be some kind of use case for it so adding a condition to preserve it would make sense.

I'm not familiar with using app specs, we're not using them to my knowledge. Here's the Podfile if it helps answer the question:

# Uncomment the next line to define a global platform for your project
platform :osx, '10.12'

target '<APPNAME>' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for <APPNAME>

end

target '<APPEXNAME>' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for <APPEXNAME>
  pod 'TLDExtract'
  pod 'SnapKit', '5.0.1'
  pod 'SwiftOTP', '2.0.1' # last version before support limited to 10.15
  pod 'CryptoSwift', '1.4.0'
  pod 'PromiseKit', '6.13'
  pod 'lottie-ios', '3.2.1'
  pod 'SVGKit', :git => '[email protected]:SVGKit/SVGKit.git', :branch => '3.x'
  
end

@dnkoutso dnkoutso modified the milestones: 1.11.3, 1.12.0 Feb 26, 2022
@scornflake
Copy link

A bit more detail why adding paths outside the bundle is not a good idea (macOS target, not iOS)

if dynamic library validation is disabled; then macOS will do a extensive check for any libraries outside the bundle. In my case, dynalic lv is disabled because I need to load external plugins.

Apple DTS have written about this in depth, here: https://developer.apple.com/forums/thread/706414

In short though, if you do a otool -l | grep -B 1 -A 2 LC_RPATH

and you see anything that is an external reference outside the bundle, the app will not load (it'll be prevented by gatekeeper)

here's an example from a brand new swift project with one pod (as framework) addded:

otool -l /Users/neil/Library/Developer/Xcode/DerivedData/TestApp-auhylmrqosjninaevcafotrjwalh/Build/Products/Debug/TestApp.app/Contents/MacOS/TestApp | grep -A 2 -B 1 RPATH
...
...
Load command 38
          cmd LC_RPATH
      cmdsize 120
         path /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx (offset 12)

Which will cause the resulting app to fail to load/run

Here's my Podfile, for reference (basically you just need at least one framework)

target 'TestApp' do
  use_frameworks!
  project "TestApp/TestApp.xcodeproj"
  pod "Alamofire"
end

Update:
I've since found that as of 12.5, an app with /Applications/Xcode-beta.app/Contents/Developer/... in its path will run. I asked Apple about this, and was advised it's a bug. So I imagine when Apple fixes it, more apps will fail for real.

In my specific case, I had another bug in my build causing LC_RPATH's into /User. However; above comment is still technically correct (thus a problem) even though right now a signed, notarized binary will actually work.

Apple recommend that your binary should have zero paths pointing outside of itself.

@dnkoutso dnkoutso modified the milestones: 1.12.0, 1.12.1 Feb 27, 2023
GetToSet added a commit to GetToSet/CocoaPods that referenced this issue Mar 30, 2023
…PATHS` referencing outside the App bundle for macOS targets. (CocoaPods#10954)
@GetToSet
Copy link

GetToSet commented Mar 30, 2023

Recently I encountered exactly the same issue after upgrading CocoaPods to 1.11.3. I've made a PR to address this issue and the following snippet in Podfile would be a temporary fix:

work_dir = Dir.pwd
installer.aggregate_targets.each do |target|
  if target.name == 'Pods-AppTarget'
    target.user_build_configurations.each do |key, name|
      if key == "Debug" || key == "Release"
        xcconfig_filename = "#{work_dir}/Pods/Target Support Files/#{target}/#{target}.#{name}.xcconfig"
        xcconfig = File.read(xcconfig_filename)
        xcconfig = xcconfig.gsub(/(LD_RUNPATH_SEARCH_PATHS = .*?)"\${DT_TOOLCHAIN_DIR}\/usr\/lib\/swift\/\${PLATFORM_NAME}"(.*)/, "\\1\\2")
        File.open(xcconfig_filename, "w") { |file| file << xcconfig }
      end
    end
  end
end

GetToSet added a commit to GetToSet/CocoaPods that referenced this issue Apr 5, 2023
…PATHS` referencing outside the App bundle for macOS targets. (CocoaPods#10954)
GetToSet added a commit to GetToSet/CocoaPods that referenced this issue Apr 5, 2023
…PATHS` referencing outside the App bundle for macOS targets. (CocoaPods#10954)
@dnkoutso dnkoutso modified the milestones: 1.12.1, 1.13.0 Apr 18, 2023
GetToSet added a commit to GetToSet/CocoaPods that referenced this issue May 17, 2023
…PATHS` referencing outside the App bundle for macOS targets. (CocoaPods#10954)
@dnkoutso dnkoutso modified the milestones: 1.13.0, 1.14.0 Sep 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants