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.
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.
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.
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 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).
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.
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 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.
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 things are installed as system binaries, not just in my home directory, so that I can be sure there is no possibility of a version being there that I don't want there. I want to be able to control exactly what device drivers and kernel modules are running. And so on.
Perhaps not all developers take this attitude; it probably depends on what kinds of things you are developing.
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.
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?)
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.
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.
Hell, if you want to hide your fault, bundle a random tool or lib that you know have an issue and exploit that. It'll be much more stable than relying on a local binary.
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.
There are prebuilt binaries of up to date git distributed via .pkg. The yeast infection that is Homebrew is unnecessary
For example: https://github.com/Homebrew/legacy-homebrew/issues/35995
They don't take much space, though, and the toolchain is treated a bit better by Apple than utilities like git, vim etc.
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...
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.
If $PATH == 'a:b' and you do `export PATH=b:$PATH, then you've basically rearranged it. It may as well be 'b:a'.
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.
>> 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.
As for the "If you rely on machines like this, I am truly sorry" - I don't really blame her. She says she's sorry because she was trying to administer a system that a. has vulnerable software she couldn't easily upgrade or even remove, and b. some of the common utilities that she uses to troubleshoot Unix systems just don't work and this makes a competent Unix admin's life harder than it needs to be.
And Rachel, by all accounts, is a very competent - no, scratch that - talented administrator. So she feels the pain of not being able to use commonly available tools and not being able to keep systems as secure as she would like.
If you feel offended by this, then it seems to me you are actively looking to be offended and you have your own agenda.
All in all, it really feels as if it was written from the perspective of someone that does not usually work with OS X and does not know the system well. In other words, she has not done her homework. Which is fine, if you acknowledge what you don't know. But then the condescending tone would be totally out of place.
The sentiment is there, and it does not help in spreading the message, unless what you really want is to flare up all the emotions. Otherwise, it's not the best course of action.
Fun fact, since we're comparing default system installations, my Ubuntu apparently still has git 2.5.0. I suppose I should find some PPA or something to update it.
The repositories can be similar to OS X in terms of providing really outdated versions of many packages. The same day Ubuntu releases a new version of the OS, packages can already be over a year out of date from the releases made by the software's developer.
The distros won't update the official repositories with newer versions of software once the version is pinned during the testing phase of the OS, due to the extensive amount of quality assurance that goes into ensuring system-wide stability. Their reasons are justified, but the end result still means you're typically not running the best and latest of anything.
Things are a little more difficult to understand with versioning in Linux. You may have git 2.5.0, but if you're on a release of the distro for which support is still ongoing, those CVEs are probably fixed due to backported security patches that don't bump the software's version number. In this manner, official repositories on Linux distros usually give you outdated software in terms of new features, but keep you entirely up to date in terms of security.
Information for Ubuntu in particular: https://wiki.ubuntu.com/StableReleaseUpdates
And then... TIL about the backports repository: https://help.ubuntu.com/community/UbuntuBackports
I've been using Macs for 30 years, including OS X since the 10.0 beta, and the recent changes have left me with a "sentiment against OS X" not unlike the "sentiment against Mac OS" that we had in the 90s when things went pear shaped.
There were people saying we shouldn't speak ill of System 7.5 back then, too.
OS X isn't a systemically marginalized group, it's a product that people are increasingly unhappy with. You may disagree as to why, or with the trade-offs involved, but we're not ignorant as you think we are; SIP likely isn't mentioned because it's obvious.
$ git --version
git version 1.9.1
Unacceptable.Stability is not the same thing as insecurity. As long as a stable release is supported, the maintainer promises to keep it secure. If your version of git had that vulnerability, Ubuntu would have backported the patches/fixes and made it available to you.
The version number 1.9.1 is a release identifier, not a security status identifier.
So fun fact indeed :)
I got the updated brew version downloaded already.
Do this to disable it:
sudo chmod -x /Applications/Xcode.app/Contents/Developer/usr/bin/git 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?IIRC, 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. % xcrun --find gitwat
so the command would be:
sudo chmod -x /Library/Developer/CommandLineTools/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)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.
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=...
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.
No, you can simply download the command line tools that Apple provides free of charge - which the homebrew install script in fact does.
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...
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.
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.
Some of us prefer MacPorts. (Not that this changes anything to the argument you're making.)
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/gitIn 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.
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.
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.p += (dir + "/");
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.
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.
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.
The real way out is to eventually change to a language where safety is opt-out and not opt-in, like in C++.
I have always been on the C++, in the C vs C++ wars, but I am also aware of all those developers that just code C with a C++ compiler, hence opt-in.
If it makes you happy I can use the ANSI C++ section number instead.
So any place that is against templates and exceptions, usually rules out the standard library on those arguments.
Then you have the software houses, whose C++ code is actually C with a C++ compiler that use the bloat and slow arguments against the library.
I don't remember them by heart, but there were a couple CppCon 2014 talks where this type of arguments was discussed.
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.
When it comes to memory safe languages, your choices do not boil down to "Rust or nothing".
Of course, Mercurial gives lie to this assumption.
What it matters is if it is fast enough for the use case being targeted.
As side note I remember when C compilers for home computers generated worser code than junior Assembly programmers.
It takes a lot more than a toolchain to write fast code.
Even then, Mercurial is implemented in Python and quite usable
The fact that a Java rewrite of git actually exists demonstrates the falsity of this statement.
Otherwise yes, it could even be rewritten in Ruby, as falcolas suggested...
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.
I'm not suggesting that C -> Rust is easier than or quite as easy as C -> C++, just that it is much easier than C -> most other languages, and that it is close enough to C -> C++ that it is worth investigating. It is definitely more robust than the minimal definition of "incremental."
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.
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'.
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.
(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.)
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.)
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?
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.
Best I can find is the following article:
https://reverse.put.as/2015/10/12/rootfool-a-small-tool-to-d...
I'd still love to know their thinking behind put git into a directory that SIP makes deliberately hard to update! I mean, git is additional software and not even part of their base operating system, my understanding about SIP was that it was meant to prevent people from tampering with the underlying system software and installing rootkits.
git (and ssh for that matter) aren't going cause rootkits by themselves - and all they are doing is forcing people to use homebrew to install versions that's aren't protected by SIP!
From a sysadmin's perspective this makes a lot of sense: beyond malware, I've seen security and stability problems caused by installers from large companies, developers cowboying up with “sudo make install", etc. but it definitely puts the onus on Apple to ship updates promptly.
I basically think that if Apple want to lock down their ecosystem and prevent folks from updating their own software, then they have a duty to provide timely updates that address security bugs. Currently they don't seem to be doing that.
Why would you install Xcode on such a important box?
And if I want to troubleshoot something odd, it would be nice to be able to hook in dtrace - without rebooting the server, flipping a switch to disable the "feature", and then troubleshoot my server's issue.
If this is such a critical issue, then reboot your Mac and disable SIP. 5 minutes and done. In the time it's taken you to post all your comments here, you could have fixed it.
[edited to add]
It's not like SIP was a secret - it was one of the major features of El Capitan. Didn't you do any research before upgrading your mission critical server to El Capitan?
https://github.com/gdbinit/rootfool
Incidentally, calm down a bit - you sound pretty outraged yourself!
You might want to address the dtrace issue though - let's say you didn't want to disable the protection that SIP provides in making the /usr filesystem immutable. How do you then run dtrace on system utilities when troubleshooting?
Genuinely curious how you answer that.
Edit to ask another question: another question for you, as you seem to have the answers here: why does Apple install git in a directory that is under the control of System Integrity Protection? Why not under /usr/local? It's not exactly a "system utility" - it's a DVCS and not in any way critical to the running of the system. Hell, I'd not even consider it system software.
And how does Apple do this? The last time I installed the XCode command line tools, I don't recall that I had to reboot my system, so it looks like Apple do indeed have an update mechanism to overwrite the files. In which case it is one exploit away from disabling the file immutability protections afforded by SIP...
I can imagine git might be necessary for applying some updates (on FreeBSD svn is a critical part of the base system, because one way to update is by svn updating the source and rebuilding).
From their readme: "P.S.: 10.11.4 update removed csr_set_allow_all() function used to enable/disable SIP. It means this code does not work on El Capitan 10.11.4 or newer versions when released."
Also even when it did work it needed you to get a Kernel Extension signing certificate from Apple - which they could (probably) revoke pretty easily when they saw it being misused.
Of course, there is a utility that sets the flag in recovery mode, unless there is a specially built kernel that only exists in that mode (I'm no OS X expert, there could be) then there must be some way of bypassing the protections. If you can still load a kernel extension then it occurs to me that you can still bypass it.
This seems to be your pattern when you get upset. You've told someone else they were being defensive, now you're saying I need to calm down.
I guess that's easier than rebooting a server and turning off SIP.
If Apple truly doesn't want me to use dtruss, then why do they bundle it?
Looks like this is the command:
csrutil enable --without dtraceIn our case I think rebooting the server works, but you can't be aware of all usecases.
sudo xcodebuild -license sudo xcode-select --installThe 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.
$ 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.
nvram boot-args="rootless=0"
EDIT: Actually, it looks like that no longer works. Dammit.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?)
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/
(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?
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.
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.
"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.
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.
Bugs are a matter of perspective. If alleged bugfixes actually make you modify your currently working setup, then I don't consider that much of an actual bugfix, just something that makes me do work for no real benefit:
http://stevelosh.com/blog/2012/04/volatile-software/
I like Debian stable. Two years is an entirely reasonable amount of time to be able to have most software in my OS immutable except for security fixes. For the tiny amount of software for which I may want the bleeding edge, there are language-specific "package" "managers" (lol npm) or I can just backport the software myself.
It's not a huge problem either as long as Linux is used almost exclusively by professionals and mostly on servers.
But freezing everything for years puts too many people in a situation where they just have to upgrade for one reason or another. It's not always their choice and it's rarely a desire for change that makes them do it.
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.
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.
The way that folks get themselves into a mess and get malware installed are largely via programs with network access. Locking down the /usr directory isn't going to prevent this sort of thing from occuring - what will stop it is not allowing users to run as admins by default, which OS X is doing already.
At which point, the way malware will get installed is via software vulnerabilities, in things like git. It won't be occurring because Apple stopped me from turning off the execute flag on potentially vulnerable programs like the git that they install by default.
You need to be able take claim ownership from TrustedInstaller, so administrators only: yes (you'll need to acquire a UAC token, but the GUI prompts you automatically). You'll also need to turn off installation integrity to prevent Windows from replacing the file. All documented. It isn't obfuscated in any way whatsoever and I figured it out first time in 2 minutes with no Google.
Security through obfuscation is known to be a broken concept.
Isn't this security through obfuscation precisely what Apple are doing right now?
1. add a repository with up-to-date version
2. update the system
It couldn't be any simpler.
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.
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.
EDIT: OK. So the fixes were backported
"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
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.
For those unfamiliar, now you know
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.