known UUID and metadata consistency
One of the problems with ReiserFS was that a fsck --rebuild-tree would look through all the disk contents for blocks that appeared to be metadata. A hostile user could create a file in their home directory (or /tmp or anywhere else) that contained ReiserFS metadata which would be linked into the filesystem on a --rebuild-tree, by doing that I created a SUID root file as non-root on a ReiserFS system. Also ReiserFS was inherently unsuitable for storing filesystem images as that could mess up the filesystem.
I believe that BTRFS uses a UUID for each filesystem that is included in every metadata block which will make it very unlikely that two runs of mkfs.btrfs will result in the same UUID. Therefore there should be no risk of a filesystem image stored in a file messing up a filesystem.
Is it possible for a hostile user to create a file that could get linked in to a filesystem by btrfsck? /dev/disk/by-uuid/ is world readable so the UUID of the filesystem is not secret. Apart from the fact that a correct tree (which can be verified by checksums) won't link to data blocks as metadata what assurance do we have that hostile or corrupt data blocks can't be treated as metadata?
Signature · 2 lines
My Main Blog http://etbe.coker.com.au/ My Documents Blog http://doc.coker.com.au/
Quoted 13 lines · Russell Coker
One of the problems with ReiserFS was that a fsck --rebuild-tree would look through all the disk contents for blocks that appeared to be metadata. A hostile user could create a file in their home directory (or /tmp or anywhere else) that contained ReiserFS metadata which would be linked into the filesystem on a --rebuild-tree, by doing that I created a SUID root file as non-root on a ReiserFS system. Also ReiserFS was inherently unsuitable for storing filesystem images as that could mess up the filesystem.
I believe that BTRFS uses a UUID for each filesystem that is included in every metadata block which will make it very unlikely that two runs of mkfs.btrfs will result in the same UUID. Therefore there should be no risk of a filesystem image stored in a file messing up a filesystem.
Quoted 6 lines
Is it possible for a hostile user to create a file that could get linked in to a filesystem by btrfsck?
/dev/disk/by-uuid/is world readable so the UUID of the filesystem is not secret. Apart from the fact that a correct tree (which can be verified by checksums) won't link to data blocks as metadata what assurance do we have that hostile or corrupt data blocks can't be treated as metadata?
"Possible, but very difficult to accomplish in an undetectable
way."
I think there's two cases here:
a) The chunk tree is whole and consistent
b) We need to (or have been asked to) rebuild the chunk tree from scratch
In the first case, btrfsck has all the pointers to the chunk tree
block(s) from the superblock, and therefore knows which areas of the disk(s) are meant to be metadata and which are meant to be data. In order for a data block to end up being considered by btrfsck, it would have to be turned into metadata. This is difficult, but not impossible -- it can happen if it's written as data, the FS is balanced so the data chunk is moved elsewhere, a metadata chunk is written in place, and none of the metadata blocks moved into that chunk overwrites the evil block. _Then_ btrfsck would have to be scanning metadata for tree blocks, which it generally doesn't do, I think.
In order for this to be dangerous, we would then need to have
something pointing at this evil block (which in a good filesystem it wouldn't), or to have some detailed scan pick it up and attempt to incorporate it. This means that it's going to have to have things like the correct (or nearly-correct) transid, and it's got to have good pointers to other metadata blocks -- a task complicated by the fact that in order to get to this point, we've just balanced the FS which has moved *everything* around to new addresses.
In the second case, it's a much simpler case for an attacker -- you
could potentially construct a whole new chunk tree (typically only a few blocks in size) with a higher transid than the original FS. If the chunk tree is sufficiently badly-broken that it can't be read, then a full disk scan (e.g. btrfs-find-root) would turn up the fake as well, I think. You'd probably have to construct a whole new load of metadata as well (at least some of the other trees), and ensure that it all linked together with the right addresses.
So I think, yes, you can make fake metadata blocks, but you have to
rely on either (a) your fake data being written to exactly the right place and not overwritten by a balance, or (b) having the chunk tree broken and the admin looking for a usable set of metadata with btrfs-find-root and choosing your fake (with enough plausible complex data in it to fool them).
I've probably missed loads of points here, but I think this is a
good start for the conversation. :)
Hugo.
Signature · 5 lines
=== Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk ===
PGP key: 65E74AC0 from wwwkeys.eu.pgp.net or http://www.carfax.org.uk
--- Anyone who claims their cryptographic protocol is secure is ---
either a genius or a fool. Given the genius/fool ratio
for our species, the odds aren't good. Quoted 10 lines · Hugo Mills
a) The chunk tree is whole and consistent
b) We need to (or have been asked to) rebuild the chunk tree from scratchSo I think, yes, you can make fake metadata blocks, but you have to
rely on either (a) your fake data being written to exactly the right place and not overwritten by a balance, or (b) having the chunk tree broken and the admin looking for a usable set of metadata with btrfs-find-root and choosing your fake (with enough plausible complex data in it to fool them).
Quoted 2 lines
I've probably missed loads of points here, but I think this is a
good start for the conversation. :)
I think you've covered most of it.
One thing that looks as a show stopper is the fact that the fake data blocks that would become the metadata blocks would lie out of any metadata group. I'm not familiar with the chunk rebuilder, but this seems as a simple check to do when it tries to guess the block group layout from what it finds on disk.
Otherwise, faking the metadata block contents seems very fragile, we'd need at least some knowledge where the block will end up in the key space and also something about the adjacent blocks -- all must fit at the time when the fsck will happen.
The logical offset of the block is incorporated in the metadata blocks in the upper layers as a key and this propagates up the tree, so replacing one block pointer would disrupt the key ordering, unless it's at the beginning/end of a gap in the key space so it could point to a data blockgroup.
Replacing a chain of nodes would need a correct parent transaction ids that match the current state of the fs.
*more handwaving*
Quoted 5 lines · David Sterba
One thing that looks as a show stopper is the fact that the fake data blocks that would become the metadata blocks would lie out of any metadata group. I'm not familiar with the chunk rebuilder, but this seems as a simple check to do when it tries to guess the block group layout from what it finds on disk.
There's one more hurdle that looks tough to overcome: each metadata block records the chunk tree UUID, and this piece of information is not available to the user through ioctls, sysfs or ordinary data reads.