Indeed that works, I mentioned that it only prevented the case where /tmp/a was a symlink. In your case it's a regular directory. If we assume a blind echo "blah" > /tmp/a/b then indeed the check is bypassed. But /tmp/a/b in the symlinked 'a' case isn't always equivalent to the case where 'a' is a normal directory.
Some simple examples that I don't think are too far-fetched:
If the name of 'b' can't be determined a priori or the directory can't be filled exhaustively with all possible names for 'b', then the symlinked 'a' is required.
A program using /tmp/a/b would have some logic for creating the directory if it doesn't exist and additional logic for when it does exist.
If it does exist, the app could do a number of things, two being:
* check the ownership of the directory (using stat())
* enter the directory and remove all the files inside it
In both of these cases the non-symlinked 'a' doesn't allow for an attack. With the symlinked 'a', the ownership of the directory (assuming we're targeting root) would be root, with the normal directory it'd have ownership of the attacker.
If the application goes in and removes all the files in the directory, in the symlinked 'a' case, it removes files in the directory the attacker is targeting. In the non-symlinked case it simply removes the attacker's symlinks.
I imagine we'll have to agree to disagree on the merits of these differences.