google / fscrypt

Go tool for managing Linux filesystem encryption
Apache License 2.0
886 stars 99 forks source link

Can't encrypt ext4 filesystem if root is btrfs subvolume #339

Closed srd424 closed 2 years ago

srd424 commented 2 years ago

(Running 0.2.9, as it's what I had easily available, but I don't think this code has changed.)

My root partition is a btrfs subvolume, which means means the entry for root in /proc/self/mountinfo looks similar to this:

31 1 0:26 /rootfs / rw,relatime shared:1 - btrfs /dev/mapper/lvg2-host rw,ssd,space_cache,subvolid=267,subvol=/rootfs

Trying to encrypt my home directory, which is on an ext4 volume, I get the error "/" is not a mountpoint.

I can't see any obvious workarounds ...

srd424 commented 2 years ago

fscrypt status gives couldn't find mountpoint containing "/", which is a bit more of a clue. Interestingly, downgrading to 0.2.5 fscrypt status works fine, which makes me wonder if #213 broke something ..

srd424 commented 2 years ago

Quick and dirty hack would be options to fscrypt and libpam-fscrypt to at least allow an expert user to tell the code that they know what they're doing, it all looks a bit prescriptive at the moment :(

srd424 commented 2 years ago

0.2.7 doesn't work either, so the finger points to #154. Really evil hack of bind mounting over /proc so fscrypt sees a fake mountinfo with "/" instead of "/<subvol>" as the fourth field doesn't work, which I really don't understand (findmnt is fooled by it OK!) Only other thing I can think of something odd to do with the device numbers, but the problem is not leaping out of the code at me :(

ebiggers commented 2 years ago

fscrypt intentionally ignores some mountpoints. For example, if both a whole filesystem and a subtree of the same filesystem are mounted, then the subtree will be ignored, as fscrypt metadata should only be stored in the filesystem's root directory. This might be interacting badly with the btrfs use case where the root directory is a subvolume and the whole btrfs filesystem is mounted somewhere that is not the root directory. However, I thought that btrfs uses different device numbers for each subvolume, which would avoid this issue. I'll need to test it to figure out what's going on.

srd424 commented 2 years ago

Hmm, digging a bit more, I think it's the device number .. stat / shows 0x001c (0:28), but /proc/self/mountinfo shows 0:26. I can't actually find the code that checks this right now, but faking mountinfo with the number as returned by stat suppresses the error.

srd424 commented 2 years ago

Oh, duh, it's https://github.com/google/fscrypt/blob/6ec8ee00398c435aba7cbb68f8246c1772e12908/filesystem/mountpoint.go#L361 The 'obvious' fix to my sleep deprived brain is to stat each mount point in parseMountInfoLine() rather than trusting the device number from the file, but I don't know if this would have any implications for bind mounts etc.

ebiggers commented 2 years ago

I couldn't find a great solution, but https://github.com/google/fscrypt/pull/340 should fix this.

srd424 commented 2 years ago

That seems to work - thank you very much for the quick turnaround on this! (It was holding up the preparation of my elderly uncle's new laptop, so we're doubly grateful :)