Live data from Hacker News

Remote code execution, git, and OS X

rachelbythebay.com

381–385 of 385 posts

Re: Remote code execution, git, and OS X

#381
post #97

Earlier quoted context omitted.

Nah, the binary doesn't actually contain git. It's just a stub (in /usr/bin) that locates Xcode on the system (in /Applications/Xcode.app by default but configurable) and execs the real git binary from there. See also: https://developer.apple.com/library/mac/documentation/Darwin...

OK great. So now the question is why? I've seen this "multiplexed binary" scheme implemented elsewhere in more constrained circumstances but it doesn't really make sense to me for a desktop OS to be doing it.

Based on some Googling and my memory... the history of toolchain installation on OS X is a big mess.

In the old days, pre-2011, you would manually download the Xcode installer from Apple's site (after a free registration), and it would install stuff into both /Developer and /usr. IIRC /usr/bin/gcc was good enough for native compilation, but for iOS you would have to locate the compiler under /Developer/Platforms/something-or-other. (Today, with LLVM's ability to target multiple architectures in one compiler, the toolchain binaries are the same and only the sysroot depends on target.)

Then in 2011, Xcode was moved to the then-new Mac App Store, but the app you got on the store was just an installer (blatantly ignoring the App Store rules, and later sandboxing restrictions, that apply to everyone else), and the installation path was the same. Oh, and the store version was initially $4.99, which pissed everyone off until it was made free in the next minor update.

In 2012, Xcode was overhauled so that /Applications/Xcode.app was directly installed by the App Store and the toolchain was located inside the app bundle. This was a big improvement in part because it made the App Store's delta app updates work properly for Xcode - previously you had to keep the installer app around so it could delta update that, which doubled disk cost, and then you still had to run the installer and wait for it to re-copy the whole IDE and toolchain. It also made it easier to have multiple copies of Xcode installed side by side, and uninstallation was now a matter of dragging the app to the trash, like any other. But if you wanted standard Unix builds to work (as opposed to building within Xcode or manually specifying the compiler path), you now had to download the separate "Command Line Tools Package", which could be done either from within Xcode or directly from Apple's developer site (the latter welcomed as it saved bandwidth and disk for anyone who didn't want to download the several-GB Xcode package), and it would install a duplicate toolchain to /usr.

Finally, in 2013, the shim binaries in /usr/bin were introduced; this system has lasted to the present and has a few advantages:

- The Command Line Tools can now be mostly segregated into /Library/Developer/CommandLineTools rather than getting mixed up in /usr with the rest of the OS - however, the installer still dumps headers into /usr/include.

- If the user has the full Xcode installed, it isn't necessary to install the Command Line Tools, as the shims will just execute the binary from /Applications/Xcode.app (or wherever Xcode is installed - you can switch globally or using an environment variable). That is, unless you need /usr/include to exist.

- Of course, installing outside of /usr/bin made it easier to introduce SIP.

- Convenience: the shims are shipped with the base OS, so if you try to run a developer command and neither Xcode nor the Command Line Tools are installed, rather than 'command not found', you get a nice GUI dialog that downloads and installs the latter in one click. (Well, "nice"; if you have a configure script that probes for the compiler by trying to run it, but doesn't depend on it, and you don't want to install it, you now have to deal with a GUI dialog popping up every time you run configure. At least, this is my experience with the similar shim that exists for javac. This should be improved.)

I suppose the advantages of the first three points could mostly have also been accomplished if Apple built some system into /etc/profile or whatever to automatically add the relevant toolchain to the PATH. Why Apple decided to go with shims instead I can only guess at, but all in all it's a decent system, and it's nice that each toolchain is now mostly self-contained in one directory so they're easy to manage. Compared to most Linux distros, where compilers are just distro packages but there's no easy way to install a package to an alternate path or have multiple versions installed simultaneously (unless you build from source), I'd say it's an improvement.

Re: Remote code execution, git, and OS X

#382
post #378

Earlier quoted context omitted.

Mine is changed for Heroku, but it only prepends. I've never seen $PATH be rearranged.

If you prefix it with something already in there then it's effectively rearranged. You wouldn't do this deliberately, of course, but it happens a lot - people end up with massive PATHs because they blindly prefix when something's gone wrong and it _may_ be the solution.

I was thinking prepending and appending aren't rearranging.

Re: Remote code execution, git, and OS X

#383
post #375

Earlier quoted context omitted.

> I specifically said "as a developer" to make clear that my requirements in this respect are not necessarily the same as those of an ordinary user. I was speaking as a developer, too. What kinds of things do you count as needing "that level of control"? The things installed in my home directory include my text editor, clang and gcc, installations of Go, Node, and multiple versions of Python, etc.

> What kinds of things do you count as needing "that level of control"? As a developer, I want complete control over everything on my development machine. It's not enough to just control my home directory. I want to be able to control exactly what system services are running, so that I can test services in the same environment they'll be running in in production. I want to be able to control exactly what versions of…

I understand this point of view, and this was also my usual approach. The reason I stopped was that the result was unmanageable systems. If you wanted to change something that you had configured on system level a year before, or even just wanted to replicate it, it became a major overhead. More creative modifications could also sometimes cause conflicts on larger upgrades.

So instead, I keep my systems small. I do not install anything I don't need, and do not touch something that is not necessary. On my laptop, I have 3 "full" applications, 15 convenience tools from homebrew (bash, git, nmap, ...) and 3 kernel extensions (including one of my own) installed. Nothing else that counts as a system-wide modification. Most of my servers are completely stock Alpine, Arch or Ubuntu systems, only running static binaries I provided.

All this saves me from dependency hell, and means that I do not need to hesitate to wipe a machine for whatever reason. It takes me 5 minutes to set a new one up, including my local own work environment.

There's a different between having control (which I have, including on my OS X machine), and actually practicing it.

Re: Remote code execution, git, and OS X

#384
post #375

Earlier quoted context omitted.

> What kinds of things do you count as needing "that level of control"? As a developer, I want complete control over everything on my development machine. It's not enough to just control my home directory. I want to be able to control exactly what system services are running, so that I can test services in the same environment they'll be running in in production. I want to be able to control exactly what versions of…

I understand this point of view, and this was also my usual approach. The reason I stopped was that the result was unmanageable systems. If you wanted to change something that you had configured on system level a year before, or even just wanted to replicate it, it became a major overhead. More creative modifications could also sometimes cause conflicts on larger upgrades. So instead, I keep my systems small. I do no…

> The reason I stopped was that the result was unmanageable systems.

I haven't had this issue; but I don't leave things that I test sitting around on my development machine when I'm done testing them. So the "baseline" configuration of my development machine doesn't change much; it has the basic development tools I need and that's it. In fact, I'm not sure I see how the kind of development system you're describing is that different from the kind of development system I was describing.

> having control (which I have, including on my OS X machine)

How do you deal with the issue that prompted the original article discussed in this thread? (I assume you use the csrutil disable method that you described elsewhere in the thread?)

Re: Remote code execution, git, and OS X

#385
post #378

Earlier quoted context omitted.

If you prefix it with something already in there then it's effectively rearranged. You wouldn't do this deliberately, of course, but it happens a lot - people end up with massive PATHs because they blindly prefix when something's gone wrong and it _may_ be the solution.

I was thinking prepending and appending aren't rearranging.

The important part of my above sentence was "with something already there".

If $PATH == 'a:b' and you do `export PATH=b:$PATH, then you've basically rearranged it. It may as well be 'b:a'.

Post reply on HN