Wandering Thoughts archives

2009-07-22

Thinking like a security paranoid: an example

There's been a bunch of commotion lately over OpenSSH and how perhaps there's a 0-day exploit in an older version of it, and so on. Given this, clearly the thing to do is upgrade to a current version just in case, right?

If you think this, you're not thinking like a security paranoid. Allow me to illustrate.

Imagine that you are an attacker. You've found a vulnerability in the very latest and most recent version of OpenSSH, and you want to exploit it. However, the problem is that sysadmins are lackadaisical about updating things, especially things like OpenSSH, so there aren't many people running the new version yet. Now, you could wait for the vulnerable version to slowly spread around, but the longer you wait the greater the chance that an OpenSSH developer will spot their mistake and fix the problem. Besides, you're impatient.

(You can see where this is going.)

So you go out and make some noise to stir up doubts about the older versions, to get sysadmins and distributions thinking 'we'd better update, just in case'. Fear of a security vulnerability makes a great driver of updates, and the more publicity the better. By updating, all of these people play into your hands, because they're installing the version that's vulnerable to your exploit, and better yet they're probably doing it without a serious inspection because they feel it's semi-urgent (and thus lowering the chance that anyone else will spot the vulnerability, especially since many of the people who do such inspections will be busy looking over old versions just in case).

Now, this is a hypothetical example; I don't particularly believe that it's what is going on with the recent OpenSSH 0-day claims. But it makes a good illustration of how security people have to think; every time something peculiar happens, you look at it and ask yourself 'who benefits? if I was evil, how could I benefit from this and why would I be doing it?'

(And I think it probably also makes a good example of how unnatural it is to think like a security paranoid. If you found this example totally over the top, well, you're normal, and that's the gap between normality and serious security.)

tech/ThinkingParanoid written at 23:21:00;

A peculiar change in Linux flock() and fcntl() behavior

Here is one of those fun issues that cause me to pull out my hair (although it can give me a peculiar sense of satisfaction to track it down).

Suppose that you have two filenames, such as (not entirely hypothetically) .vacation.dir and .vacation.pag. As it happens, these filenames are actually hardlinks, so there is only one actual file involved. Now, suppose you have code that is like this C-oid pseudo-code:

fl = {F_WRLCK, SEEK_SET, 0, 0, getpid()};
fd1 = open(".vacation.dir", O_RDONLY);
flock(fd1, LOCK_EX);
fd2 = open(".vacation.pag", O_RDWR);
fcntl(fd2, F_SETLK, &fl);

If and only if you are on a sufficiently modern Linux and the files are on an NFS filesystem (possibly it depends on the NFS server), the fcntl() will fail with EAGAIN. If you don't know that the files are hardlinks, it may take you some time to realize what's going on, especially because many of the test programs you write will probably work fine (except when applied to that specific pair of files).

(But wait, it gets weirder. Replace the fcntl() with flock() and it will fail even on local filesystems and on older kernels. This behavior disagrees with the manpage, which is explicit in that separate file descriptors to the same file are treated independently. Updated: I was badly misreading the manpage and this is correct flock() behavior; treating the file descriptors independently means that separate locks on them will conflict, not that they won't. See the comments.)

In this case, Ubuntu 6.06 is not sufficiently modern but Ubuntu 8.04 is, and guess what we just did today. (If you guessed 'upgraded our mail server', you win.)

Now, you might sensibly ask why we have code that is trying to do such a crazy thing in the first place. The answer to that is that the fcntl() is actually done in the gdbm library's dbm_open function, which errors out if it fails. We don't want to error out, we just want to serialize things, and so we need to add our own locking to do so, which needs a file, and what better file to use than the other one of the DBM database files, since we know that it has to exist.

(I am not sure what file to use as a replacement for the serialization, although clearly we need to find one.)

linux/FlockFcntlChange written at 01:05:00;


Page tools: See As Normal.
Search:
Login: Password:

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.