Bug 647322

Summary: System writes to a loop mount of a RO image.
Product: [openSUSE] openSUSE 11.2 Reporter: Carlos Robinson <carlos.e.r>
Component: KernelAssignee: E-mail List <kernel-maintainers>
Status: RESOLVED FIXED QA Contact: E-mail List <qa-bugs>
Severity: Major    
Priority: P5 - None CC: jeffm
Version: Final   
Target Milestone: ---   
Hardware: x86-64   
OS: openSUSE 11.2   
Whiteboard: maint:released:11.2:36688
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---

Description Carlos Robinson 2010-10-18 10:04:40 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.
Comment 1 Jeff Mahoney 2010-10-18 19:44:15 UTC
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.
Comment 2 Carlos Robinson 2010-10-25 02:09:10 UTC
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.
Comment 3 Swamp Workflow Management 2010-10-28 11:04:43 UTC
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)
Comment 4 Jeff Mahoney 2010-11-22 21:19:09 UTC
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.