Remote code execution, git, and OS X
rachelbythebay.com
rachelbythebay.com
Ironically, when they do that, they also make it difficult, impractical, or impossible for you to upgrade or disable vulnerable software (in this case, an old, insecure version of git with remote-code-execution vulnerability).
People like Richard Stallman have been warning about this sort of thing for decades.
It is inconvenient that these dev tools are not updated frequently (bash, zsh, and many other command line tools are terribly out of date), but it is not terribly difficult to install a fresh version in parallel.
Sure, but the fact remains that OS X deliberately hides things from you, and you have no way of knowing that you've found all the hidden things. And for a developer, I think that's unacceptable. I want full root access to my development machine, not a dumbed down version of "root" that doesn't let me mess with certain things. This is one of the key reasons why I will not use a Mac as a development machine.
The binaries are protected by "rootless mode"/System Integrity Protection, but you can disable this and get full root access to your development machine. Just run "csrutil disable" from recovery mode (It wouldn't really help if you could disable it from a running system).
The only locked down things on OS X are proprietary GUI stuff, such as windowserver or some menubar API's. Regular operation is not locked down.
The link between /usr/bin/git and /Application/Xcode.app/Contents/.../bin/git is hidden.
I don't know how you would discover this: ls indicates /usr/bin/git is a regular file rather than a symlink; stat -f "%i" says the two files have different inodes, so they're not hardlinked.
What is the nature of the link, and how would you find this if you didn't already know?
/usr/bin/git is a "toolshim" that effectively calls "xcrun git" (it actually calls xcselect_invoke_xcrun, from /usr/lib/libxcselect.dylib, if you really want the details - this can be found by inspecting the binary). xcode-select's manpage tells you that these shims call the respective binary in the active developer directory, whereas xcrun's manpage describes its capabilities in more detail.
It took about 3 minutes to figure out.
The old saying that Linux is for geek, and other OSes are for regular computer user is still quite true. The truth is, half of the time I don't touch the root of OS X. Why would I need to. I use brew to install my git, I am good. Similarly I don't modify my Ubuntu workstation unless I have a reason to. I can't remember the last time I needed to edit anything really special to get my Mac customized or let along attaching a debugger to a running process on Mac. Well my work doesn't involve troubleshooting Mac software so there is no incentive. I spend more time on customizing my VIM then customizing my OS X.
So back to reality, please use what fits your desire and your mileage. I just need a computer in a Linux-like environment so I can navigate shit around and complete my work on a nice polished computer.
In theory I could even switch operating systems completely (within the *NIX family) with minimal work.
As an ordinary user, this can be perfectly reasonable. 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. Developers need a level of control over their machines and configurations that ordinary users, as a rule, don't.
Having control does not mean you have to change anything. Also, most developers are regular users.
I'm not arguing that it's okay that Apple bundles an affected version of git, but if they start undoing what you did to protect them, I don't think they can be helped. I'm a bit pessimistic in this sense, but I keep getting surprised by the kind of crap that makes their way onto peoples machines, sometimes people that really should know better.
As for the environment, that's the same for any UNIX, though. .bashrc is run only if you start bash. Getting an ubuntu dist. to set up your environment variables in GUI applications certainly won't be fixed with a .bashrc. It might inherit /etc/profile, if you're lucky.
For OS X, launchd handles the environment by simply being the one responsible for starting the applications that you inherit your environment from (such as Finder, Dock and Spotlight), and .bashrc is just a file that bash executes itself that might set additional environment variables. This is not unlike a Linux setup, where you only inherit environment variables written in .bashrc if you started the application from bash.
(OS X does have a path management system for shells in the form of path-helper and /etc/path.d/, but that's run through the profile, which won't affect GUI applications.)
I'm not really trying to defend OS X here, other than pointing out that if you cut out the proprietary GUI stuff, it's basically just your run-of-the-mill custom UNIX dist. As a long time Linux user (I use a Mac as laptop, because screw trying to get Linux working perfectly on a laptop), I find everything to be an equal pain in the ass to deal with. systemd or launchd, X11 or windowserver, Finder, Nautilus, Konqueror or even Windows Explorer - They all suck. Pick your poison.
Stupid applications aren't the ones to worry about. As an attacker, if I know that every mac has a git vulnerability, and all I have to do is to hard code a path to it, then I'm going to do that.
Not really, they just need to be able to modify a single file owned by the user (.bashrc), or just the current shell session (again, with a variable owned by the user). Re-ordering `/usr/bin` and `/usr/local/bin` in $PATH isn't that hard.
With this level of privileges, you can, on any machine, mask existing binaries with whatever you want. It is hardly related to the issue with git.
You have the user's execution rights only; you don't have root access.
> Thr machine is already pwned, and one privilege escalation bug away from being completely lost.
This is true of any program the user runs. The fix is for the user to not run untrusted code. Trusted code should not be modifying .bashrc without the user's knowledge.
> With this level of privileges, you can, on any machine, mask existing binaries with whatever you want.
And the user can unmask them just as easily. It's not at all the same as having root access.
That is also what I said - code execution. Like the git RCE gives you. But, it would be rather redundant to use code execution as a local user to obtain code execution as a local user, no? With .bashrc, it doesn't matter how new your git is, there's no reason to exploit it.
Also, privilege escalation bugs.
> This is true of any program the user runs. The fix is for the user to not run untrusted code. Trusted code should not be modifying .bashrc without the user's knowledge.
Exactly my point. If the .bashrc has been modified in an evil way, as you suggested, you're screwed because someone is executing code as your user, which is usually exactly what they need. Add one privilege escalation, and they can do whatever they want, but that's not really necessary, depending on what they want to do.
In essence, if I can write to a file of my liking on your machine as your user, then I have code execution rights as your user (potentially with a time delay, depending on what I tamper with).
> And the user can unmask them just as easily. It's not at all the same as having root access.
Exactly, like installing a different version of git with homebrew and masking the old one. Also, privilege escalation bugs. I think you're forgetting how common they are. A decent set of privilege escalation bugs is part of any decent hackers toolkit.
If someone modifies .bashrc, as you initially suggested ("Not really, they just need to be able to modify a single file owned by the user (.bashrc), or just the current shell session (again, with a variable owned by the user)"), then the git RCE is redundant, as you already have obtained code execution on the machine.
Code execution how? How are you going to execute code on my machine if you don't have physical access to it? That's why the RCE makes a difference.
> it would be rather redundant to use code execution as a local user to obtain code execution as a local user, no?
As I understood the comment that started this subthread, it was talking about using a remote code execution vulnerability to modify .bashrc. Nobody, as far as I can tell, in this discussion is talking about having local (i.e., physical) access to the machine.
I don't think so. Running as your user, I could add an entry to your .bashrc that execs your shell with an injected shared library that hides itself (e.g. any child process that reads your .bashrc sees an unmodified version). Same for GUI apps, by touching other files. The only way to detect it would be to log into another account or single user mode, just like a real rootkit may only be detectable if you use another system to examine the disk.
Access to a user's account is no less damaging to them than root access — the damage just doesn't extend to the rest of the machine which, in many cases, doesn't matter.
I don't think you'll ever be able to help people that follow internet advice blindly, for these people, it might be better not to bundle anything at all.
I think it's a fairly common measure to download a lot of what OS X comes with over homebrew, simply because OS X's versions tend to be annoyingly outdated (Like bash 3.2.57, vs. 4.3.42 from homebrew).
Any GNU/GNU, GNU/Linux, or GNU/anything system could do exactly the same thing without violating any terms of the GPL. Requiring a reboot into a special "I know I'm messing with the system" mode in order to mess with important core binaries is not an unreasonable way protect the user from malware, and does not in any way abridge any of the core freedoms Stallman promotes.
(and yes, you literally can run a command and reboot your Mac to be able to make changes to the protected stuff, and the process to do this is well-documented)
Sure, Apple should ship a fix, but there are ways around it for now.
To me, this is the biggest problem, and it's not just Homebrew. Any source package manager that uses Git will potentially have this problem. With a vulnerable Git on your system, you have to second-guess every build script you ever run that might make use of Git, to make sure it obeys the path you set instead of choosing its own.
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.
There's nothing I hate more than the inability to fix things that are broken on my system or the fact that I would have to jump trough a lot of unnecessary hoops to do it.
The few small advantages are just not worth it in the end for me.
With the homebrew git installed, the stars really have to align for that vulnerability to be exploited. You can possibly get a user to clone from your repository. But if you can also get him to use the git version you want, we're at the point where you apparently have control of the system already.
In comparison with linux, this vulnerability pales in comparison to the-common-void-that-shall-not-be-talked-about, i. e. the around 400 gems, npms, brews, pips, go(es?), roles and ppas installed & running on a typical dev workstation, no matter if it's Linux or Mac. It's just a matter of time until someone gets his version of leftpad installed on >100,000 workstations & servers before he flips the switch to turn them into cryptolocked hostages.
Also: I'd hate if I had to fiddle around with kernel parameters to get printing, sleeping, networking, waking, font-displaying, account-switching, video-playing, time-knowing or up-backing to work every time canonical decides it's time for a new <x>subsystem. I love linux on the server, but maintaining a function desktop system is simply a waste of time. A somewhat evil waste of productivity, actually, because it feels like work and at the same time provides those frequent little victories that can turn it into an obsession.
On the other hand. Once you master this (which is not such a huge intend), you know your system.
Which is a valuable "smart skill" when developing (even web apps). For example, knowing how to use awk and sed instead of having to start a node or ruby instance is a thing that shows a developer actually knows how to run linux and not only "how to run stuff on linux".
You'll also understand $PATH. Which apperently is a thing most MAC users do not understand. Having to start "docker-shell" because they don't know how to extens theyr $PATH is a freaking joke and a workflow killer.
I understand that MAC's are comfortable to use and maintain. But as developers we should embrace leaving the comfort zone and face the real deal. We shouln't be some bunch of kids who need mac because it's comfortable.
Lets grow from little kids that need "mama mac" to take care of our stuff and become grown up's that can handle a system, because they know the system.
I don't think I'm special here, but I'm for sure a subset of Mac users. My point is, seeing a Mac at someone's desk shouldn't make you assume they're idiots, just like you don't assume someone's a l33t-ub3r-h4ck3r if they're walking around with a lenovo.
I don't get the idea that Mac users are attracted to the system because they cannot handle windows or linux – they just don't want to. Isn't it kinda obvious that the stereotype can't survive when you see >3/4 of all google employees using Macs?
But hey, maybe I should write an App that randomly introduces bugs into my stack to finally learn a bit more about it. And when my car breaks down, I'll be thankful for the learning experience.
Some of us prefer MacPorts. (Not that this changes anything to the argument you're making.)
But I don't want to dismiss this vulnerability – it's so easy to fix on Apple's part that they don't have an excuse. There are a few too many neglected corners of their OS where they seriously have to get their act together. But in practical terms, people focus too much on the technologically exciting or Apple/MS/<other divisive entity>-drama provoking vulnerabilities, while there's probably like one or two people working in software who actually verify every hash of every download and audit the source code for every version of every vim plugin they install.
Or, in Old New Thing terms, "it rather involved being on the other side of this airtight hatchway".
https://blogs.msdn.microsoft.com/oldnewthing/20140529-00/?p=...
I prefer Mint if I need a Ubuntu fork that's quite stable and has most things already configured generally used at work and as my personal desktop I use Arch mostly because compatibility with the hardware required the latest kernel at the time.
I like playing with the latest features and not having to install the OS every other year because some major update from canonical broke everything.
As far as fiddling with the kernel I never had to do anything like that to get the things you mentioned working the most I had to do is install some software and configure it correctly.
In the years I've been running Arch on the desktop it only breaks on average about 2 or 3 times a year which is quite decent considering it's a rolling release and I haven't had any major issues with mint since I started using it about 2-3 years ago.
I crashed the window manager a few times but that's about it in comparison Unity used to crash on me constantly and the entire experience of using plain Ubuntu as a desktop was awful so I understand why you would be against using it if that is all you knew of Linux as a desktop.
At home when I'm futzing around I don't mind (and quite enjoy it). But at work I don't have time to diddle my device drivers and OMG the xorg.conf crap I had to deal with in the past that still give me nightmares...
This is also a bit weird since getting git installed on OSX in the first place requires it's own hoop: "buying" the free copy of XCode and installing it is required for the command line tools that homebrew relies on.
sudo cp /Applications/Xcode.app/Contents/Developer/usr/bin/git /somewhere/to/backup/just/in/case
sudo rm /Applications/Xcode.app/Contents/Developer/usr/bin/git
sudo ln -s /usr/local/bin/git /Applications/Xcode.app/Contents/Developer/usr/bin/git sudo cp /usr/local/bin/git /Applications/Xcode.app/Contents/Developer/usr/bin/gitI got the updated brew version downloaded already.
Do this to disable it:
sudo chmod -x /Applications/Xcode.app/Contents/Developer/usr/bin/git sudo cp /Applications/Xcode.app/Contents/Developer/usr/bin/git /somewhere/to/backup/just/in/case
sudo rm /Applications/Xcode.app/Contents/Developer/usr/bin/git
sudo ln -s /usr/local/bin/git /Applications/Xcode.app/Contents/Developer/usr/bin/git $ ls $(git --exec-path) chmod: /Applications/Xcode.app/Contents/Developer/usr/bin/git: No such file or directory
I don't have Xcode installed, do I have to install it back to do this?so the command would be:
sudo chmod -x /Library/Developer/CommandLineTools/usr/bin/gitIIRC, you might have a /usr/bin/git executable but that's not actually git, all it does is shows a GUI that prompts you to install XCode
Yea, /usr/bin/git is still there:
$ git --version
$ git version 2.6.4 (Apple Git-63)
But glad to know it won't do anything.wat
>> If you rely on machines like this, I am truly sorry. I feel for you.
I don't feel sorry for myself. Odd that a stranger finds it necessary to offer me their sympathy, let alone condescending pity.
"Sometimes I think about all of those pictures which show a bunch of people in startups. They have their office space, which might be big, or it might be small, but they tend to have Macs. Lots of Macs. A lot of them also use git to do stuff, perhaps via GitHub, or via some other place entirely. There are lots of one-off repos all over the place."
If you can see a cheap shot in that paragraph, then you are reading things that aren't there. A blog post gives a certain amount of freedom for the author to elaborate on a theme.
You seem a bit defensive. I'm not sure why, but I certainly don't think that Rachel was attacking those who use Macs.
>> I know, I'll just strace it to see what it execs! Oh wait, this isn't Linux. Uh, I'll dtruss it to see what it execs!
Someone who is not in the process of bashing as much as possible would have simply said something like "I'll dtruss it (OS X's equivalent to Linux's strace) to see what it execs". All the exclamation marks and passive aggressive "Uh", "Oh wait", "Well, sorry" phrasing to drive home just how terribly awful the operating system is.
The closing section with the "If you rely on machines like this, I am truly sorry" sealed it. This clear dislike for the ecosystem adds - at least for me - new meaning to the opening paragraph. Typical startup bashing for "trying to be hip and trendy". It's hardware and an operating system. Everyone has a preference for the tools they use; there's no need for passive aggressive hostility.
They don't take much space, though, and the toolchain is treated a bit better by Apple than utilities like git, vim etc.
There are prebuilt binaries of up to date git distributed via .pkg. The yeast infection that is Homebrew is unnecessary
Perhaps the main cause for delay is the associated QA efforts to make sure that other components in the stack which depend on git don't break in the case that git has broken binary compatibility (i.e. changed its public interface).
It is too late for there to be an expedient update from Apple. The vulnerability was disclosed to oss-security over a month ago, on March 15[0]. SUSE had a patch out the next day[1]. By March 24, Debian, Ubuntu, Red Hat, CentOS and Oracle had all issued fixes.[2]
[0]: http://www.openwall.com/lists/oss-security/2016/03/15/5
[1]: http://lists.opensuse.org/opensuse-security-announce/2016-03...
In the best case the attacker would fake an email that looks like it came from your IT department. Even if you were suspicious, a quick search on the web would confirm that Apple really ships a vulnerable binary. So you believe the email is real. Then you go along and replace the binary with the malicious binary provided in the mail.
The fixed binary needs to be shipped by Apple.
> So, what's the big deal? Crappy C code gets exploited every day, and we upgrade it, and then we're "safe" until the next huge hole that's been there forever is reported. (In the meantime, people party with their private stash of vulnerabilities.)
A lot of Linux C utilities would benefit from such a treatment.
My impression is that some projects are already experimenting with or using C++ in their C code bases, so C to C++ is quite likely.
However, using C and C++ together in a project is especially easy. If I were to do this, I would first get the code base compiling with a C++ compiler (this already brings some extra type safety) and is not particularly difficult.
Then I'd start replacing C code blocks with safer C++ code. This could mean changing a function, some parameter-passing conventions, replacing char* with std::string, etc.
This has the biggest chance of success I feel, and there's already success stories and strategies available that describe this method. E.g: GCC.
When it comes to memory safe languages, your choices do not boil down to "Rust or nothing".
Otherwise yes, it could even be rewritten in Ruby, as falcolas suggested...
Many other languages support C linkage in a way that's comparable to C++.
The point is that code like in that function is a nightmare to write correctly and test in plain C.
I do like to use C++ a lot on personal projects, but there I can make full use of C++ best practices.
At work, I tend to avoid using it, because most C++ developers I have met on my career, actually use it as Better C, keeping all safety loopholes from C.
I had my share of spending weeks tracking down memory corruption issues.
Argument 2 is valid, but only applies to kernels, and also only applies to 1992 (it works a lot better now).
(That's probably why I misunderstoood your statement an argument against C++ on its own merits.)
Something like:
std::string path_name(std::vector<std::string> const& dirs, std::string const& name) { std::string p; for(auto const& dir : dirs) { p += (dirs + "/"); } p += name; return p; }
should work. If you feel like it, you can also add something like:
std::size_t len = name.size();
for(auto const& dir : dirs) { len += dir.size(); }
p.reserve(len);
Of course, len may overflow, but even if it does, all the harm that causes is that the string will have to reallocate memory during growth until running in a segfault when further memory allocation fails.I'm just trying to point out that the convenience of some C++ standard library features is not isolated to C++, and C++ is not a "memory safe" language by meaning of the word.
p += (dir + "/");
Again, C++ does not make anything safer, and its types can easily be replicated in any other language.
The "n" variants are a joke in terms of security, even the C99 annex, that was demoted to optional in C11.
I call them a joke, because tracking the pointer and length separately is hardly an improvement in terms of security.
The only improvement that the "n" variants added is that the null character is always added to the end, instead of how strncpy does it, by only adding the character if there is enough space.
(EDIT: Some stuff has changed since February, so some of these claims are now out of date. But not all of them, the overall situation is still similar.)
The solution here is actually quite trivial: just restrict filenames to 255 bytes and nesting to 255 levels, which limits paths to 64KB at most. Anyone trying to use git repositories exceeding either of those limits should be considered insane.
I think that using std::string would prevent the bug, because it would throw length_error on append. string::resize can be used to avoid excessive allocations.
Sanity checks would provide extra safety, but the code should fail cleanly even without them.
Funny, because I've actually been locked up for being insane five times. Speaking from experience, they'd only consider me insane if I said something like 255 was an important number because there are two sides to every problem and five fingers on each hand, and the path, which two feet take, is six one way / half a dozen the other, to the four corners of the earth, which is the natural limit.
So... you don't really know what insane is. Jus' sayin'.
You'll need to put an updated subprocess.py in your Python path, editing the one provided by OS X is prevented by the System Integrity Protection... ¯\_(ツ)_/¯
My take is that the OS-installed tools, such as git or Python, are generally for use by the system and not for use by me for software development.
For those of us who have only installed the Command Line Tools, you will find the Apple supplied git at /Library/Developer/CommandLineTools/usr/bin/git
so the command to disable this vulnerable version is:
sudo chmod -x /Library/Developer/CommandLineTools/usr/bin/gitThere is nothing hugely special about their tools - every other app apparently has to install into a different location as best practice, so I don't understand why Apple don't follow their own guidelines!
They don't. Plenty of comments explain where the Xcode git actually is.
They have three perfectly reasonable directories they can install into, which is what they recommend that application developers do when installing their software:
/Applications /Library /usr/local
So why do they feel the need to link git into /usr/bin? They could link it into /usr/local/bin - the $PATH variable includes this directory already.
You state that plenty of comments explain where the Xcode git actually is, but that misses the point entirely. Why is it linked into /usr/bin?
The real thing that is bugging me, is finding out what /usr/bin/git really is.. which this article doesn't answer.
Is it a standalone immutable executable that the file system is aware of, or something else?
Right now, I wish I had a mac.
nvram boot-args="rootless=0"
It seems to me that this is related to that feature. Although, I don't get why it looks like the two files are hardlinked but you can modify one -- maybe it's because this magic was only applied to the /usr/bin directory (and thus a hardlink to the file can still be modified). That's a bit dumb IMO, but I can imagine this being a bug in the OS X kernel.Unfortunately, I'm not sure how to actually create such files (maybe if I disable System Integrity Protection, create a file and hardlink to it and then re-enable SIP). If I figure it out on my friends' MacBook I'll comment below.
EDIT: Okay, so it might not be what I said earlier. If I do something along the lines of:
1. Disable SIP (csrutil disable in recovery).
2. Create a file in /usr/bin and hardlink it to a non-SIP location (like $HOME).
3. Re-enable SIP (csrutil enable).
4. Try to change the permissions on either of the hardlinks.
It will fail. So presumably SIP correctly propagates permissions to all dentries. I'm not sure what's happening then.
/usr/bin/git is a small wrapper that invokes the actual git from either the command line developer tools or from xcode (whatever you have selected with `xcode-select`)
I mean, SIP is generally only partial protection anyway, isn't it?
Yes, I know that wrappers isn't new. But if they wanted to secure it they could've kept the actual binary in a SIP-protected directory.
One of the features of SIP is that barring interference (e.g. using csrutil in the recovery boot mode) one can be fairly confident about the contents of a number of directories to the extent that one can (in the boot time trampoline that system upgrading uses) delete everything in them and install in their place the contents of signed installation media, with no worries that this accidentally conflicts with local state (e.g. locally installed versions of system software or dynamic libraries or the like).
Actually doing a "Reinstall the SIP-protected parts of Mac OS X" thus has some pretty good guarantees of non-destructiveness and thoroughness, and "Safe Mode" can ignore anything that isn't SIP-protected, thus producing a much more predictable post-boot environment than in previous version of Mac OS X.
Some thought went into the initial design and SIP evolved during the beta process; until fairly late, one could subvert SIP with union mounts for example, and there was to-and-fro on what third party things one could could simply move from /System/Library to /Library (notably from /S/L/Filesystems to /Library/Filesystems).
It's interesting to compare with the approach taken by SmartOS (for example; https://wiki.smartos.org/display/DOC/Zones), which in the global zone and in Solaris zones is strictly read only for everything under /usr, and which in the global zone refuses to persist changes under /etc and a few other places. Some of the reasoning is the same (known state can make for safer version upgrading); but some of the reasoning is to take advantage of other virtues too, specific to SmartOS's focus on hosting VMs.
Going back further, network-mounted read-only filesystems like /usr was fairly commonplace in environments where UNIX workstations were plentiful, with per-workstation customization often made user-specific (e.g. via moira, back in the day... http://kb.mit.edu/confluence/pages/viewpage.action?pageId=39...) and non-persisted, along the lines of the guest login in modern Mac OS X.
Back to your last sentence: Apple tools (including the App Store) can't work around the sandboxing without a system restart -- once the sandboxing service is running, it stays running and cannot be disabled, and a complex trampoline is needed in single user mode to work around sandboxing early in the startup process (even in single user mode). XCode does not install anything that really requires a reboot, and is wholly optional, so forcing a reboot to install or uninstall it seems heavy-handed compared to trampolines that rely on xcode-select. (Similar to other optional installs like X11). Moreover, XCode itself is signed and by default you will still get warned (and your tool will not be run) if something under XCode has been modified or substituted.
Nothing really prevents them from protecting optional installs using SIP if they decide it's better that way. And indeed, local admins familiar with Sandboxing can extend SIP protections to them themselves via /Library/Sandbox, where one can add further (but not weaker than /S/L/S) rules.
It can't be removed because it's a file that comes with OS X and is therefore covered by System Integrity Protection, which prevents you from deleting or tampering with system components, even as root.
Is there a list somewhere of dangerously old software Apple have shipped to me that I should reinstall with brew immediately?
Apple is doing something new which basically keeps you from twiddling certain system-level programs without going to fantastic lengths.
Not even root is enough to do it.
Can someone explain it to me?
The big market isn't developers but end users who have no idea how to protect themselves from real threats and who don't use git. And for them sandboxing, signed executables, verified boots and other measures make life far better.
If you are a developer using a Mac you most likely use brew or some sort of vm/container system anyway.
Only a very large company could come up with such an amazingly awful idea. I can just imagine the meeting where this was decided that it would "protect" users where someone said "Freeze all the system binaries even from the end users, that will make them more secure!".
Anyway, so only system updates can update the OS X system? Which involves a system reboot? How does the "system protected" software get updated?
But not making it easy to update flawed software sounds like a great vector for malware.
$ brew install git
$ git --version
git version 2.8.1 0 find /usr/bin/ /usr/local/bin/ /usr/sbin/ /sbin/ |grep -w git$ find /usr -name git -type f -xdev -exec {} -v \;
All your invocation of find does is enumerate every file (or directory) under /usr named "git" and execute it with the -v option. In addition to dumping a lot of error messages, all that would do is eventually run "/usr/bin/git -v" and inform you that yep, your system still has the vulnerable version of git installed.
In other words, tadfisher's point, which I now wish had been made explicitly, is that simply installing the fixed version of git is possibly insufficient to secure your system. You also ought to either disable /usr/bin/git or convince yourself that no program will invoke it. Disabling /usr/bin/git is probably easier.
$ brew install git
==> Downloading https://homebrew.bintray.com/bottles/git-2.6.1.el_capitan.bo...
$ git version
git version 2.6.1
$ brew upgrade git
Error: git 2.6.1 already installed
brew update
brew upgrade githttps://developer.apple.com/library/mac/documentation/Darwin...
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.
I'm far from a fan of Apple's protectionism, and yet this doesn't seem like anything to be up in arms about.
The poster's point, as you haven't understood it, is that by preventing updates of utilities like the system git, vulnerabilities remain available on the system. This makes the system less secure, and the only way to fix the security issue is to disable the security feature that is preventing the security vulnerability from being fixed.
In other words - by making system files immutable even to root, it's not exactly making the system any more secure.
I understood the point perfectly well, and that's why I think it's a bit overblown. This security feature is precisely designed to prevent you from modifying your system and encourage you to defer that to Apple. It should be obvious that such a feature will also prevent you from fixing things yourself, which Apple either hasn't gotten around to fixing or refuses to. But since they give you some way of disabling it, you just do that and fix it yourself (and presumably SIP will then protect your fixed version of git?)
nvram boot-args="rootless=0"
EDIT: Actually, it looks like that no longer works. Dammit. git --version
git version 2.1.4
Should I be worried?For my developer machine I prefer rolling updates, so I run Debian 'testing' on that one, which is basically a snapshot of what is going to be the next stable release, with daily updates (there are also distros like Arch that only do rolling release).
There's also a kind of in-between option: http://backports.debian.org/
"unstable" with apt-listbugs installed works quite well for me. Sometimes I have to boot grml to roll back packages (check out the grml-rescueboot package), but that's very rare.
(a) upgraded to the latest version
(b) upgraded to the latest version that the developer considers API compatible
(c) kept frozen
Is there a way to do that with the debian package management system?
I would recommend trying to keep things separate like that (or via something like docker/kvm/vagrant/etc) -- rather than trying to mix'n'match. You'll likely be the only one trying a particular combination of versions, and it's unlikely to be much fun.
But, you can get a little closer if you run debian Stable and also include apt sources from testing and/or unstable, and do some clever things in /etc/apt/preferences to pin package priorities. It can get messy fast, though.
It works well if developers make sure that bugs in older versions of their software are fixed even after the next version is released. I think that is the case with a lot of infrastructure sort of software.
But if developers do not maintain old versions and fix bugs only by releasing a newer version of their software, then debian's approach leads to stability only in the sense of a reliably buggy system.
And I don't mean buggy in the sense that all software is buggy. I mean buggier than the best compatible release version available.
git (1:2.1.4-2.1+deb8u2) jessie-security; urgency=high
* Non-maintainer upload by the Security Team.
* Fix remote code execution via buffer overflows (CVE-2016-2315, CVE-2016-2324) (Closes: #818318)
-- Salvatore Bonaccorso <carnil@debian.org> Fri, 18 Mar 2016 06:20:38 +0100
The Debian Changelog (where you find this stuff out) is linked from the package page at https://packages.debian.org/jessie/git (on the right hand side under Debian Resources) or you can look at /usr/share/doc/git/changelog.Debian.gz on your system.Since they haven’t changed this package, there may be another reason besides security. For example, some important group at Apple or a big customer may have created a dependency on "git" functionality, and they want to carefully test any change on a large scale before proceeding. Just because it isn’t wise for important things to depend on fragile environments doesn’t mean they can ignore those environments when making changes.
The problem with simple versions is that an update seems to be all or nothing: you can’t easily fix a small security hole when starting from a few versions ago because you have to consider anything else that changed. Ideally, systems are designed in enough layers that small updates really are practical without affecting other features.
> They are basically screwed until Apple deigns to
> deliver a patched git unto them
Actually, no. Don't use the tools that come pre-installed.All you have to do* is:
brew install git
*and make sure that brew installs are prioritised in your $PATH. Which you should do anyway.Just installing git from Homebrew or MacPorts is not enough to be safe from this remote code execution.
That said, any program that invokes /usr/bin/git directly instead of /usr/bin/env git would still be vulnerable.
It's not as big of a problem as the article makes it out to be so long as you install a newer version of git.
If you're really concerned, the filesystem restrictions mentioned can be bypassed by booting into safe mode. Though it's still not a good idea to mess with the default program installations since Apple may depend on that particular version of git for some program.
If it is there without XCLT, then anyone reading this is more than capable of removing it, and dealing with anything that subsequently can't find it.
Of course, the overall issue of not being able to modify the software on your own system still holds.
GPLv3[0] introduced protections again Tivoization:
--
"“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM)."
--
[0]: https://www.gnu.org/licenses/gpl.html
You can install your own version of Git, yes. But Apple, as a distributor, cannot prevent you from installing a replacement for the software that it distributes. If, wherever they provide the source code to Git, they do provide a method to replace the currently install software, then that wouldn't be a problem.
Now, I did find this:
https://opensource.apple.com/source/Git/Git-17/Makefile
Which does indeed have an install target.
Can anyone tell me if this replaces the original program, or at least provides information necessary to remove it?
Instead, we get the updates once ever so often and these security updates don't even come close to fixing all the security bugs in the software on my OS X operating system.
It's really not very good. Vendors such as Apple and Microsoft are far, far too slow in releasing updates.
https://opensource.apple.com/source/Git/Git-58/src/git/revis...
Function is path_name, nlen type should be size_t and there shouldn't be integer overflow in the first loop.
Edit:
OK, Xcode 7.2 security notes mentions Git vulnerability CVE-2015-7082 (older than the ones in questions), and Xcode 7.3 doesn't mention any fixed vulnerabilities in Git, so I guess it's vulnerable and NOT patched.
1. OS X ships with a "git" command in /usr/bin that merely looks for the real "git" command inside Xcode or somewhere else and executes it.
2. The vulnerability is inside the real "git" (shipped with Xcode/the Command Line Tools) that Apple apparently cannot be bothered to update.
3. The author complains about not being able to make /usr/bin/git non-executable because of SIP.
Why not just make the real "git" command non-executable and be done with it?
And since /usr/bin/git apparently just delegates, the git vulnerability at least won't endanger most users, since they don't have the real (old, vulnerable, thanks Apple) git installed.
sudo chmod a-x /Applications/Xcode.app/Developer/usr/bin/git
Done. Running /usr/bin/git will now proxy you a permission denied error.
You can install brew git and then link XCode git to homebrew version.
I can't wait until a worm or similar wide-spread disaster hits the Apple eco-system and just deletes the system when it's done spreading.
Besides which, this whole question is missing the point somewhat. There is no easy way of updating the system supplied tools like git, even if you wanted to. The latest version of git is v2.8, and I think it would be grand if we could use a version less than 6 months old!
Hell, the same goes with any other system software.
Exactly. Apple are update nazis themselves (support for old versions is being dropped quickly and users are forced to update), so they should at least apply the same logic to system tools.
1. add a repository with up-to-date version
2. update the system
It couldn't be any simpler.
Apple are known to be tardy in taking their time to release security fixes unfortunately. This whole point might be mitigated if they were more responsive, but they aren't terribly. Your average Linux distro is far faster at updates even on LTS releases than Apple...
I'm worried about when (not "if") this changes, people are snapping up Macs all around me and thusly the platform won't be protected from worms due to" hacker disinterest" forever.
because driver support
Is it feasible for Mac users to downgrade to older OS X?
It makes absolutely no sense to downgrade OS X versions to avoid SIP. It's quicker to just disable SIP than to downgrade the OS.
"Notes about this update: Security fix for CVE-2016-2315, CVE-2016-2324 (by updating to 2.5.5)."
So looks like they have backported the security fixes
EDIT: OK. So the fixes were backported
https://packages.debian.org/jessie/git
~ git --version
git version 2.1.4I'm confused about how 'Macs' and 'free software' go together?
(What point is moot?)
Software updates are super important of course, and apple should be better at pushing the latest software updates, but I wish the title reflected that.
No it's not, it's blasting OS X for shipping software with a known remote execution vulnerability, and not allowing the user to easily upgrade that software themselves due to new OS-wide security policies.
But the author didn't try that. They merely speculated that
upgrading over top of that will almost certainly screw something up later.
I upgraded the Subversion that's shipped with XCode 5 on OS X 10.9 (both old, I know) without any problems simply by manually replacing the files in /Applications/XCode.app/Contents/Developer/usr/bin.
It's the 'System Integrity Protection' feature in conjunction with this version of git that the author has a problem with.
For those unfamiliar, now you know