linuxmount-point

test -x in Mounted Filesystem


I'm using QEMU to test Raspberry Pi before putting the image onto an SD card. I'm setting up an automated script to put some files onto the Pi, among other things, so that when I put the SD card into the Pi, it is immediately usable. I think I've run into a quirk in how permissions work, but I'm not sure.

When you run test -x, the file is supposed to be executable. Basically, the x bit is supposed to be on for your user. However, this doesn't seem to apply to files inside mounted filesystems.

The host is Ubuntu, and the guest backing image is Raspberry Pi Buster. I created the mountpoint with guestmount, because I was mounting a snapshot, not the original, and this seems to be the only/best way to do that. The basic flow was:

qemu-img convert -Oqcow2 raspberry-pi.img raspberry-pi.qcow
qemu-img create -f qcow2 snapshot.qcow -b raspberry-pi.qcow
sudo guestmount -a 'snapshot.qcow' -i 'mountpoint/'

For example, I have a file outside the repository. The file I'm testing inside the mountpoint was created by root, so I chmoded this file to root for comparison:

$ sudo ls -l --author ~/test/file
-rw-r--r-- 1 root root root 1133 Oct  8 21:43 /home/me/test/file
$ sudo test -x ~/test/file && echo 'exists' || echo 'doesn\'t exist'
doesn't exist

However, for a file inside the mountpoint, with the same permissions, the test is successful:

$ sudo ls -l --author mountpoint/home/pi/test/file
-rw-r--r-- 1 root root root 0 Oct  8 22:41 mountpoint/home/pi/test/file
$ sudo test -x ~/test/file && echo 'exists' || echo 'doesn\'t exist'
exists

Why is the file inside the mountpoint executable, whereas the one outside is not executable? Is this because the mounted filesystem is a different architecture (x86 vs. ARM)? Is it because I'm using guestmount, and the filesystem isn't the real filesysem, but an amalgamation of the snapshot & the original file? Or is this just the way mounting works? Where can I find more resources on this peculiar behavior, like other permission quirks I might encounter?

If you need any more information about the host or guest, please ask.


Solution

  • This is a bug in libguestfs used by guestmount. You can see it here:

      /* Root user should be able to access everything, so only bother
       * with these fine-grained tests for non-root.  (RHBZ#1106548).
       */
      if (fuse->uid != 0) {
        [...]
        if (mask & X_OK)
          ok = ok &&
            (  fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IXUSR
               : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IXGRP
               : statbuf.st_mode & S_IXOTH);
      }
    

    The FS takes a shortcut saying that since you're root you have full access, so there's no point checking the permissions.

    As you've demonstrated, this is not true. Root should only have execute permissions for directories, and for files where at least one of the execute bits is set.

    I was unable to build the project to submit a patch, but you can file a bug.