Bugzilla – Bug 647322
System writes to a loop mount of a RO image.
Last modified: 2010-11-22 21:19:09 UTC
System writes to a loop mount of a RO image. 11.2 Linux Telcontar 2.6.31.14-0.1-desktop #1 SMP PREEMPT 2010-09-17 11:32:00 +0200 x86_64 x86_64 x86_64 GNU/Linux Procedure: Creating a reiserfs image. Telcontar:~ # md Prueba Telcontar:~ # cd Prueba Telcontar:~/Prueba # dd if=/dev/zero of=test.img bs=100M count=10 10+0 records in 10+0 records out 1048576000 bytes (1.0 GB) copied, 2.46084 s, 426 MB/s Telcontar:~/Prueba # losetup /dev/loop7 test.img Telcontar:~/Prueba # losetup -a /dev/loop7: [0807]:221618 (/root/Prueba/test.img) Telcontar:~/Prueba # mkreiserfs /dev/loop7 ... ReiserFS is successfully created on /dev/loop7. Telcontar:~/Prueba # md mount Telcontar:~/Prueba # mount /dev/loop7 mount/ Telcontar:~/Prueba # df mount/ Filesystem 1K-blocks Used Available Use% Mounted on /dev/loop7 1023964 32840 991124 4% /root/Prueba/mount Telcontar:~/Prueba # mount | grep mount /dev/loop7 on /root/Prueba/mount type reiserfs (rw) Telcontar:~/Prueba # echo Hello World > mount/Hello_World Telcontar:~/Prueba # l mount/ total 8 drwxr-xr-x 4 root root 112 Oct 16 04:10 ./ drwxr-xr-x 3 root root 4096 Oct 16 04:10 ../ -rw-r--r-- 1 root root 12 Oct 16 04:10 Hello_World Telcontar:~/Prueba # Telcontar:~/Prueba # umount mount/ Telcontar:~/Prueba # losetup -d /dev/loop7 Telcontar:~/Prueba # chmod a-w test.img Telcontar:~/Prueba # l total 1025032 drwxr-xr-x 3 root root 4096 Oct 16 04:10 ./ drwx------ 104 root root 20480 Oct 16 04:00 ../ drwxr-xr-x 2 root root 4096 Oct 16 04:03 mount/ -r--r--r-- 1 root root 1048576000 Oct 16 04:10 test.img Telcontar:~/Prueba # Telcontar:~/Prueba # losetup /dev/loop7 test.img Telcontar:~/Prueba # mount /dev/loop7 mount/ Telcontar:~/Prueba # echo Hello World > mount/Hello_World_wo Telcontar:~/Prueba # l mount/ total 12 drwxr-xr-x 4 root root 144 Oct 16 04:13 ./ drwxr-xr-x 3 root root 4096 Oct 16 04:10 ../ -rw-r--r-- 1 root root 12 Oct 16 04:10 Hello_World -rw-r--r-- 1 root root 12 Oct 16 04:13 Hello_World_wo Yagh. It has written to a R/O file. Go figure. I tested again and compared the images before and after (md5)... modified. I have also repeated the test with an image created on a filesystem that I then mounted RO. Loop-mounted the file-image (reported RO, correct), and writes to the mount failed - as it should. The problem is when the underlying filesystem is R/W, and the image has no write permissions - but after the image file is loop mounted, the system writes to it. Telcontar:~/Prueba # md5sum test.img f470d7cde52f63a5277db92574e473ea test.img Telcontar:~/Prueba # losetup /dev/loop7 test.img Telcontar:~/Prueba # mount -o ro /dev/loop7 mount/ Telcontar:~/Prueba # touch mount/should_fail touch: cannot touch `mount/should_fail': Read-only file system Telcontar:~/Prueba # umount mount/ Telcontar:~/Prueba # losetup -d /dev/loop7 Telcontar:~/Prueba # md5sum test.img 7df29dd1dab33deb5e70d8bbd53a1894 test.img Telcontar:~/Prueba # l test.img -r--r--r-- 1 root root 1048576000 Oct 18 12:00 test.img See the md5? It has changed... This breaks forensics and safe storage of backup images. Notice that I have reported similar issues over the years.
Ok, this is a simple issue of the fix for bug #441062, also reported by you, not making it into 11.2. 11.1 doesn't have this issue because it's based on the SLE11 kernel, which has the fix. 11.3 doesn't have this issue because the fix was accepted upstream for 2.6.34. I've added the fix to 11.2. Thanks for drawing my attention back to it.
I'm testing this in 11.3, for completeness (2.6.34.7-0.3-desktop). Same test as above, but I will not copy-paste the exact outputs (it is another machine). 1) R/W filesystem, RO image. Loop mounted with default, automatic, options. It writes and modifies the image. 2) R/W filesystem, RO image. Loop mounted with "-o ro". Writes to filesystem fails. However, the md5sum changes... something was written. 2b) Same, but no attempt to write a file, ie: calculate md5sum, mount R/O, umount, md5sum again: it has changed. 3) RO filesystem Image is automatically mounted R/O, and writes to it fails. Image file is not modified. Point 1 and 2 prove that the bug is present in 11.3 too. Sorry. In case "1" Mount should also automatically mount as RO as in case "3", as the image has no write permissions. Permissions are ignored. But even if it is mounted RO, at least the journal is altered. This has been tested with a reiserfs image - I don't know if other filesystems are affected. I can try that as well, if requested.
Update released for: kernel-debug, kernel-debug-base, kernel-debug-base-debuginfo, kernel-debug-debuginfo, kernel-debug-debugsource, kernel-debug-devel, kernel-debug-devel-debuginfo, kernel-default, kernel-default-base, kernel-default-base-debuginfo, kernel-default-debuginfo, kernel-default-debugsource, kernel-default-devel, kernel-default-devel-debuginfo, kernel-desktop, kernel-desktop-base, kernel-desktop-base-debuginfo, kernel-desktop-debuginfo, kernel-desktop-debugsource, kernel-desktop-devel, kernel-desktop-devel-debuginfo, kernel-pae, kernel-pae-base, kernel-pae-base-debuginfo, kernel-pae-debuginfo, kernel-pae-debugsource, kernel-pae-devel, kernel-pae-devel-debuginfo, kernel-source, kernel-source-vanilla, kernel-syms, kernel-trace, kernel-trace-base, kernel-trace-base-debuginfo, kernel-trace-debuginfo, kernel-trace-debugsource, kernel-trace-devel, kernel-trace-devel-debuginfo, kernel-vanilla, kernel-vanilla-base, kernel-vanilla-base-debuginfo, kernel-vanilla-debuginfo, kernel-vanilla-debugsource, kernel-vanilla-devel, kernel-vanilla-devel-debuginfo, kernel-xen, kernel-xen-base, kernel-xen-base-debuginfo, kernel-xen-debuginfo, kernel-xen-debugsource, kernel-xen-devel, kernel-xen-devel-debuginfo, preload-kmp-default, preload-kmp-desktop Products: openSUSE 11.2 (debug, i586, x86_64)
What you're describing isn't a bug. It's a misunderstanding of what the terms mean. Read-only file system does /not/ mean that the file system metadata will not be touched, just that users including root will not be allowed to modify it. Things like journal replay are allowed. Read-only block device means that absolutely no writers will be allowed. Note that in all your examples above, you were operating as root. When you do an losetup without a -r, it assumes you want a read-write encapsulation. If the caller doesn't have permission to open the file read-write, it will be denied permission to set up the encapsulation. Here's the hitch: When the user is root, then all permissions are granted except when the file is marked immutable (chatter, not chmod) or the underlying file system is read-only. Since permissions are granted, the block device is created read-write. If a regular user, who happens to have permission to open a /dev/loop device, has a read-only file, then the read-write open of the file would be disallowed by the kernel so the loop driver could not be passed a read-write file descriptor. As a result, the underlying block device would be read-only. So, for the behavior you're looking for, set up the loop device with losetup -r /dev/loop* <file> and then mount read-only and you'll get a truly read-only device and file system. If you normally use mount -r -oloop blahblah to set up the mount point, then you might have a case for mount not having a method to set up the block device read-only. If you want to pursue that, please file a new report against the Basesystem component. I misunderstood the original description of the bug to mean that it was a duplicate of the original reiserfs issue where it would attempt to write to a read-only block device and fail -- or it would fail when there was no reason for it to fail. In that case, I'm going to close this one as FIXED.