←back to thread

MacOS Catalina: Slow by Design?

(sigpipe.macromates.com)
2031 points jrk | 2 comments | | HN request time: 0.419s | source
Show context
jaimehrubiks ◴[] No.23273553[source]
In our company many of us have similar issues. I have always loved OSX but this time it is driving me crazy. I though the issue was some sort of company antivirus/firewall, or it could even be a combination of that and this issue (maybe my vpn + path to company firewall is what magnifies the issue in this post). The thing is that some commands take 1 second, some others take 2 minutes or even more. Actually, some commands slow down the computer until they are finished (more likely, until they just decide to start).

For example, I can run "terraform apply" and it could take up to 5 minutes to start, leaving my computer almost unusable until it runs. The weird thing is that this only happens sometimes. In some cases, I restart the laptop and it starts working a little bit faster, but the issue comes back after some time.

It's already been a few months since I try to run every command from a VM in a remote location, since I am tired of waiting for my commands to start.

I have a macbook air from 2013 which never had this issue.

Any easy fix that I could test? Disconnecting from the internet is not an option. Disabling SIP could be tried, but I think I already did and didn't seem to fix it, plus it is not a good idea for a company laptop.

Don't we have some sort of hosts file or firewall that we can use to block or fake the connectivity to apple servers?

replies(5): >>23273869 #>>23273932 #>>23274213 #>>23275720 #>>23278491 #
derefr ◴[] No.23274213[source]
IIRC the big thing that changed with 10.15 for CLI applications is that BSD-userland processes (i.e. ones that don't go through all the macOS Frameworks, but just call libc syscall wrappers like fopen(2)) now also deal with sandboxing, since the BSD syscall ABI is now reimplemented in terms of macOS security capabilities.

Certain BSD-syscall-ABI operations like fopen(2) and readdir(2) are now not-so-fast by default, because the OS has to do a synchronous check of the individual process binary's capabilities before letting the syscall through. But POSIX utilities were written to assume that these operations were fast-ish, and therefore they do tons of them, rather than doing any sort of batching.

That means that any CLI process that "walks" the filesystem is going to generate huge amounts of security-subsystem request traffic; which seemingly bottlenecks the security subsystem (OS-wide!); and so slows down the caller process and any other concurrent processes/threads that need capabilities-grants of their own.

To find a fix, it's important to understand the problem in fine detail. So: the CLI process has a set of process-local capabilities (kernel tokens/handles); and whenever it tries to do something, it first tries to use these. If it turns out none of those existing capabilities let it perform the operation, then it has to request the kernel look at it, build a firewall-like "capabilities-rules program" from the collected information, and run it, to determine whether it should grant the process that capability. (This means that anything that already has capabilities granted from its code-signed capabilities manifest doesn't need to sit around waiting for this capabilities-ruleset program to be built and run. Unless the app's capabilities manifest didn't grant the specific capability it's trying to use.)

Unlike macOS app-bundles, regular (i.e. freshly-compiled) BSD-userland executable binaries don't have a capabilities manifest of their own, so they don't start with any process-local capabilities. (You can embed one into them, but the process has to be "capabilities-aware" to actually make use of it, so e.g. GNU coreutils from Homebrew isn't gonna be helped by this. Oh, and it won't kick in if the program isn't also code-signed, IIRC.)

But all processes inherit their capabilities from their runtime ancestors, so there's a simple fix, for the case of running CLI software interactively: grant your terminal emulator the capabilities you need through Preferences. In this case, the "Full Disk Access" capability. Then, since all your all CLI processes have your terminal emulator as a runtime ancestor-process, all your CLI processes will inherit that capability, and thus not need to spend time requesting it from the security subsystem.

Note that this doesn't apply to BSD-userland executable binaries which run as LaunchDaemons, since those aren't being spawned by your terminal emulator. Those either need to learn to use capabilities for real; or, at least, they need to get exec(2)ed by a shim binary that knows how.

-----

tl;dr: I had this problem (slowness in numerous CLI apps, most obvious as `brew upgrade` suddenly taking forever) after upgrading to 10.15 as well. Granting "Full Disk Access" to iTerm fixed it for me.

replies(2): >>23274332 #>>23274780 #
saagarjha ◴[] No.23274780[source]
> IIRC the big thing that changed with 10.15 for CLI applications is that BSD-userland processes (i.e. ones that don't go through all the macOS Frameworks, but just call libc syscall wrappers like fopen(2)) now also deal with sandboxing, since the BSD syscall ABI is now reimplemented in terms of macOS security capabilities.

Is this actually new in macOS 10.15? I seem to recall this being a thing ever since sandboxing was a thing, even all the way back to when it was called Seatbelt.

> That means that any CLI process that "walks" the filesystem is going to generate huge amounts of sandboxd traffic, which bottlenecks sandboxd and so slows down the caller process.

Is this not implemented in the kernel as an extension? I thought the checks went through MAC framework hooks. Doesn't sandboxd just log access violations when told to do so by the Sandbox kernel extension?

> Unlike macOS app-bundles, regular BSD-userland executable binaries don't have a capabilities manifest of their own, so they don't start with any process-local capabilities (with some interesting exceptions, that I think involve the binary being embedded in the directory-structure of a system framework, where the binary inherits its capabilities from the enclosing framework.)

I am fairly sure you can just embed a profile in a section of your app's binary and call the sandboxing Mach call with that…

replies(2): >>23274947 #>>23275182 #
1. danudey ◴[] No.23275182[source]
It's a new behavior that doing 'find ~' will trigger a MacOS (GUI) permissions warning dialog when `find` tries to access your photos directory, contacts file, etc.
replies(1): >>23275686 #
2. saagarjha ◴[] No.23275686[source]
That is new, but I believe the groundwork for that was mostly laid in 10.14 and is also mostly in the kernel.