[PATCH] EXT3: ext3 block bitmap leakage

This patch fixes ext3 block bitmap leakage,
which leads to the following fsck messages on
_healthy_ filesystem:
Block bitmap differences:  -64159 -73707

All kernels up to 2.6.17 have this bug.

Found by
   Vasily Averin <vvs@sw.ru> and Andrey Savochkin <saw@sawoct.com>
Test case triggered the issue was created by
   Dmitry Monakhov <dmonakhov@sw.ru>

Signed-Off-By: Vasiliy Averin <vvs@sw.ru>
Signed-Off-By: Andrey Savochkin <saw@sawoct.com>
Signed-Off-By: Kirill Korotaev <dev@openvz.org>
CC: Dmitry Monakhov <dmonakhov@sw.ru>
[PATCH] EXT3: avoid crashing by not dividing by zero.

backport a few checks from 2.6 to avoid dividing by zero on invalid
superblocks.
2.4: fix memory corruption from misinterpreted bad_inode_ops return values

This is a 2.4 backport of a linux-2.6 change by Eric Sandeen
(commit be6aab0e9fa6d3c6d75aa1e38ac972d8b4ee82b8)

CVE-2006-5753 was assigned for this issue.

I've built and boot-tested this, but I'm not sure how to exercise
these codepaths.

Commit log from 2.6 follows.

  CVE-2006-5753 is for a case where an inode can be marked bad, switching
  the ops to bad_inode_ops, which are all connected as:

  static int return_EIO(void)
  {
          return -EIO;
  }

  #define EIO_ERROR ((void *) (return_EIO))

  static struct inode_operations bad_inode_ops =
  {
          .create         = bad_inode_create
  ...etc...

  The problem here is that the void cast causes return types to not be
  promoted, and for ops such as listxattr which expect more than 32 bits of
  return value, the 32-bit -EIO is interpreted as a large positive 64-bit
  number, i.e. 0x00000000fffffffa instead of 0xfffffffa.

  This goes particularly badly when the return value is taken as a number of
  bytes to copy into, say, a user's buffer for example...

  I originally had coded up the fix by creating a return_EIO_<TYPE> macro
  for each return type, like this:

  static int return_EIO_int(void)
  {
  	return -EIO;
  }
  #define EIO_ERROR_INT ((void *) (return_EIO_int))

  static struct inode_operations bad_inode_ops =
  {
  	.create		= EIO_ERROR_INT,
  ...etc...

  but Al felt that it was probably better to create an EIO-returner for each
  actual op signature.  Since so few ops share a signature, I just went ahead
  & created an EIO function for each individual file & inode op that returns
  a value.

Signed-off-by: dann frazier <dannf@hp.com>
intermezzo: fix uninitialized use of pointer in error path

gcc pointed out the following issue :
  dcache.c: In function `presto_set_dd':
  dcache.c:251: warning: `fset' might be used uninitialized in this function

fset is not yet assigned in the error path, so no operation must be done
with it.
udf: fix uid/gid permissions

This change made it into the 2.6 branch since 2.6.15 and fixes a problem
where the UDF code would change the ownership of files in a UDF filesystem
when they were different thatn the current user, when possible. Example: after
creating a CD using udf as a regular user, if you mounted the CD as root, the
udf code would reset the ownership of all the files on the cd, causing
unecessary write operations. I found this fix while working with an old patch
which adds packet-writing to the 2.4 kernel. This fix is from the original
author (or maintainer) of the udf code.

Note: this was fixed upstream in 4d6660eb3665f22d16aff466eb9d45df6102b254.
Remove suid/sgid bits on truncate() (CVE-2008-4210)

Hi Willy,

I noticed that CVE-2008-4210 is missing from the linux-2.4.git tree.

Don (cc'ed) proposed this:

Cc: Don Howard <dhoward@redhat.com>
Test-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit ead60d38671fb5a0aa5e4f04dbc61736f2d9461f)
Fix dnotify/close race (CVE-2008-1375)

Issue reported by Al Viro with description taken from 2.6 commit
214b7049a7929f03bbd2786aaef04b8b79db34e2 :

We have a race between fcntl() and close() that can lead to
dnotify_struct inserted into inode's list *after* the last descriptor
had been gone from current->files.

Since that's the only point where dnotify_struct gets evicted, we are
screwed - it will stick around indefinitely.  Even after struct file in
question is gone and freed.  Worse, we can trigger send_sigio() on it at
any later point, which allows to send an arbitrary signal to arbitrary
process if we manage to apply enough memory pressure to get the page
that used to host that struct file and fill it with the right pattern...
ext: Avoid printk floods in the face of directory

This is a trivial backport of the following upstream commits:

- bd39597cbd42a784105a04010100e27267481c67 (ext2)
- cdbf6dba28e8e6268c8420857696309470009fd9 (ext3)

This addresses CVE-2008-3528

ext[23]: Avoid printk floods in the face of directory corruption

Note: some people thinks this represents a security bug, since it
might make the system go away while it is printing a large number of
console messages, especially if a serial console is involved.  Hence,
it has been assigned CVE-2008-3528, but it requires that the attacker
either has physical access to your machine to insert a USB disk with a
corrupted filesystem image (at which point why not just hit the power
button), or is otherwise able to convince the system administrator to
mount an arbitrary filesystem image (at which point why not just
include a setuid shell or world-writable hard disk device file or some
such).  Me, I think they're just being silly. --tytso

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: linux-ext4@vger.kernel.org
Cc: Eugene Teo <eugeneteo@kernel.sg>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
[w@1wt.eu: backport from 2.6-stable to 2.4. Removed all ext4 references]
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit b85ad79e46390c2774a7dc2056a2a719ae97a5ac)
hfsplus: fix Buffer overflow with a corrupted image

[backport of 2.6 commit efc7ffcb4237f8cb9938909041c4ed38f6e1bf40]

When an hfsplus image gets corrupted it might happen that the catalog
namelength field gets b0rked.  If we mount such an image the memcpy() in
hfsplus_cat_build_key_uni() writes more than the 255 that fit in the name
field.  Depending on the size of the overwritten data, we either only get
memory corruption or also trigger an oops like this:

[  221.628020] BUG: unable to handle kernel paging request at c82b0000
[  221.629066] IP: [<c022d4b1>] hfsplus_find_cat+0x10d/0x151
[  221.629066] *pde = 0ea29163 *pte = 082b0160
[  221.629066] Oops: 0002 [#1] PREEMPT DEBUG_PAGEALLOC
[  221.629066] Modules linked in:
[  221.629066]
[  221.629066] Pid: 4845, comm: mount Not tainted (2.6.27-rc4-00123-gd3ee1b4-dirty #28)
[  221.629066] EIP: 0060:[<c022d4b1>] EFLAGS: 00010206 CPU: 0
[  221.629066] EIP is at hfsplus_find_cat+0x10d/0x151
[  221.629066] EAX: 00000029 EBX: 00016210 ECX: 000042c2 EDX: 00000002
[  221.629066] ESI: c82d70ca EDI: c82b0000 EBP: c82d1bcc ESP: c82d199c
[  221.629066]  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[  221.629066] Process mount (pid: 4845, ti=c82d1000 task=c8224060 task.ti=c82d1000)
[  221.629066] Stack: c080b3c4 c82aa8f8 c82d19c2 00016210 c080b3be c82d1bd4 c82aa8f0 00000300
[  221.629066]        01000000 750008b1 74006e00 74006900 65006c00 c82d6400 c013bd35 c8224060
[  221.629066]        00000036 00000046 c82d19f0 00000082 c8224548 c8224060 00000036 c0d653cc
[  221.629066] Call Trace:
[  221.629066]  [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[  221.629066]  [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[  221.629066]  [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[  221.629066]  [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[  221.629066]  [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[  221.629066]  [<c0107aa3>] ? native_sched_clock+0x82/0x96
[  221.629066]  [<c01302d2>] ? __kernel_text_address+0x1b/0x27
[  221.629066]  [<c010487a>] ? dump_trace+0xca/0xd6
[  221.629066]  [<c0109e32>] ? save_stack_address+0x0/0x2c
[  221.629066]  [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
[  221.629066]  [<c013b571>] ? save_trace+0x37/0x8d
[  221.629066]  [<c013b62e>] ? add_lock_to_list+0x67/0x8d
[  221.629066]  [<c013ea1c>] ? validate_chain+0x8a4/0x9f4
[  221.629066]  [<c013553d>] ? down+0xc/0x2f
[  221.629066]  [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
[  221.629066]  [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[  221.629066]  [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[  221.629066]  [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[  221.629066]  [<c0107aa3>] ? native_sched_clock+0x82/0x96
[  221.629066]  [<c013da5d>] ? mark_held_locks+0x43/0x5a
[  221.629066]  [<c013dc3a>] ? trace_hardirqs_on+0xb/0xd
[  221.629066]  [<c013dbf4>] ? trace_hardirqs_on_caller+0xf4/0x12f
[  221.629066]  [<c06abec8>] ? _spin_unlock_irqrestore+0x42/0x58
[  221.629066]  [<c013555c>] ? down+0x2b/0x2f
[  221.629066]  [<c022aa68>] ? hfsplus_iget+0xa0/0x154
[  221.629066]  [<c022b0b9>] ? hfsplus_fill_super+0x280/0x447
[  221.629066]  [<c0107aa3>] ? native_sched_clock+0x82/0x96
[  221.629066]  [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[  221.629066]  [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[  221.629066]  [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
[  221.629066]  [<c041c9e4>] ? string+0x2b/0x74
[  221.629066]  [<c041cd16>] ? vsnprintf+0x2e9/0x512
[  221.629066]  [<c010487a>] ? dump_trace+0xca/0xd6
[  221.629066]  [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
[  221.629066]  [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
[  221.629066]  [<c013b571>] ? save_trace+0x37/0x8d
[  221.629066]  [<c013b62e>] ? add_lock_to_list+0x67/0x8d
[  221.629066]  [<c013ea1c>] ? validate_chain+0x8a4/0x9f4
[  221.629066]  [<c01354d3>] ? up+0xc/0x2f
[  221.629066]  [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
[  221.629066]  [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[  221.629066]  [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[  221.629066]  [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[  221.629066]  [<c0107aa3>] ? native_sched_clock+0x82/0x96
[  221.629066]  [<c041cfb7>] ? snprintf+0x1b/0x1d
[  221.629066]  [<c01ba466>] ? disk_name+0x25/0x67
[  221.629066]  [<c0183960>] ? get_sb_bdev+0xcd/0x10b
[  221.629066]  [<c016ad92>] ? kstrdup+0x2a/0x4c
[  221.629066]  [<c022a7b3>] ? hfsplus_get_sb+0x13/0x15
[  221.629066]  [<c022ae39>] ? hfsplus_fill_super+0x0/0x447
[  221.629066]  [<c0183583>] ? vfs_kern_mount+0x3b/0x76
[  221.629066]  [<c0183602>] ? do_kern_mount+0x32/0xba
[  221.629066]  [<c01960d4>] ? do_new_mount+0x46/0x74
[  221.629066]  [<c0196277>] ? do_mount+0x175/0x193
[  221.629066]  [<c013dbf4>] ? trace_hardirqs_on_caller+0xf4/0x12f
[  221.629066]  [<c01663b2>] ? __get_free_pages+0x1e/0x24
[  221.629066]  [<c06ac07b>] ? lock_kernel+0x19/0x8c
[  221.629066]  [<c01962e6>] ? sys_mount+0x51/0x9b
[  221.629066]  [<c01962f9>] ? sys_mount+0x64/0x9b
[  221.629066]  [<c01038bd>] ? sysenter_do_call+0x12/0x31
[  221.629066]  =======================
[  221.629066] Code: 89 c2 c1 e2 08 c1 e8 08 09 c2 8b 85 e8 fd ff ff 66 89 50 06 89 c7 53 83 c7 08 56 57 68 c4 b3 80 c0 e8 8c 5c ef ff 89 d9 c1 e9 02 <
f3> a5 89 d9 83 e1 03 74 02 f3 a4 83 c3 06 8b 95 e8 fd ff ff 0f
[  221.629066] EIP: [<c022d4b1>] hfsplus_find_cat+0x10d/0x151 SS:ESP 0068:c82d199c
[  221.629066] ---[ end trace e417a1d67f0d0066 ]---

Since hfsplus_cat_build_key_uni() returns void and only has one callsite,
the check is performed at the callsite.

Signed-off-by: Eric Sesterhenn <snakebyte@gmx.de>
Reviewed-by: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 96de10c0b613c1f0f3712ef4e4d30b52884b68c6)
FAT: do not continue in fat_get_block if bmap fails

There is no use in continuing the write operation after fat_bmap() fails.
(This successfully killed a VFAT FS for me).
The corresponding code in 2.6 does return here as well, AFAICT.

Signed-off-by: Stefan Seyfried <seife@sphairon.com>
Signed-off-by: Willy Tarreau <w@1wt.eu>