All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
	Zwane Mwaikambo <zwane@arm.linux.org.uk>,
	Theodore Ts'o <tytso@mit.edu>,
	Randy Dunlap <rdunlap@xenotime.net>,
	Dave Jones <davej@redhat.com>,
	Chuck Wolber <chuckw@quantumlinux.com>,
	Chris Wedgwood <reviews@ml.cw.f00f.org>,
	Michael Krufky <mkrufky@linuxtv.org>,
	Chuck Ebbert <cebbert@redhat.com>,
	Domenico Andreoli <cavokz@gmail.com>, Willy Tarreau <w@1wt.eu>,
	Rodrigo Rubira Branco <rbranco@la.checkpoint.com>,
	Jake Edge <jake@lwn.net>, Eugene Teo <eteo@redhat.com>,
	torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk,
	ext4 development <linux-ext4@vger.kernel.org>,
	Eric Sandeen <sandeen@redhat.com>,
	Eugene Teo <eugeneteo@kernel.sg>
Subject: [patch 15/27] ext: Avoid printk floods in the face of directory corruption (CVE-2008-3528)
Date: Thu, 23 Oct 2008 21:34:37 -0700	[thread overview]
Message-ID: <20081024043437.GP30828@kroah.com> (raw)
In-Reply-To: <20081024043303.GA30828@kroah.com>

[-- Attachment #1: ext-avoid-printk-floods-in-the-face-of-directory-corruption.patch --]
[-- Type: text/plain, Size: 7501 bytes --]

2.6.27-stable review patch.  If anyone has any objections, please let us 
know.

------------------
From: Eric Sandeen <sandeen@redhat.com>

This is a trivial backport of the following upstream commits:

- bd39597cbd42a784105a04010100e27267481c67 (ext2)
- cdbf6dba28e8e6268c8420857696309470009fd9 (ext3)
- 9d9f177572d9e4eba0f2e18523b44f90dd51fe74 (ext4)

This addresses CVE-2008-3528

ext[234]: 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>

---
 fs/ext2/dir.c |   60 +++++++++++++++++++++++++++++++++-------------------------
 fs/ext3/dir.c |   10 ++++++---
 fs/ext4/dir.c |   11 +++++++---
 3 files changed, 50 insertions(+), 31 deletions(-)

--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page
 	return err;
 }
 
-static void ext2_check_page(struct page *page)
+static void ext2_check_page(struct page *page, int quiet)
 {
 	struct inode *dir = page->mapping->host;
 	struct super_block *sb = dir->i_sb;
@@ -146,10 +146,10 @@ out:
 	/* Too bad, we had an error */
 
 Ebadsize:
-	ext2_error(sb, "ext2_check_page",
-		"size of directory #%lu is not a multiple of chunk size",
-		dir->i_ino
-	);
+	if (!quiet)
+		ext2_error(sb, __func__,
+			"size of directory #%lu is not a multiple "
+			"of chunk size", dir->i_ino);
 	goto fail;
 Eshort:
 	error = "rec_len is smaller than minimal";
@@ -166,32 +166,36 @@ Espan:
 Einumber:
 	error = "inode out of bounds";
 bad_entry:
-	ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
-		"offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
-		dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
-		(unsigned long) le32_to_cpu(p->inode),
-		rec_len, p->name_len);
+	if (!quiet)
+		ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
+			"offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+			dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+			(unsigned long) le32_to_cpu(p->inode),
+			rec_len, p->name_len);
 	goto fail;
 Eend:
-	p = (ext2_dirent *)(kaddr + offs);
-	ext2_error (sb, "ext2_check_page",
-		"entry in directory #%lu spans the page boundary"
-		"offset=%lu, inode=%lu",
-		dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
-		(unsigned long) le32_to_cpu(p->inode));
+	if (!quiet) {
+		p = (ext2_dirent *)(kaddr + offs);
+		ext2_error(sb, "ext2_check_page",
+			"entry in directory #%lu spans the page boundary"
+			"offset=%lu, inode=%lu",
+			dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+			(unsigned long) le32_to_cpu(p->inode));
+	}
 fail:
 	SetPageChecked(page);
 	SetPageError(page);
 }
 
-static struct page * ext2_get_page(struct inode *dir, unsigned long n)
+static struct page * ext2_get_page(struct inode *dir, unsigned long n,
+				   int quiet)
 {
 	struct address_space *mapping = dir->i_mapping;
 	struct page *page = read_mapping_page(mapping, n, NULL);
 	if (!IS_ERR(page)) {
 		kmap(page);
 		if (!PageChecked(page))
-			ext2_check_page(page);
+			ext2_check_page(page, quiet);
 		if (PageError(page))
 			goto fail;
 	}
@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void *
 	for ( ; n < npages; n++, offset = 0) {
 		char *kaddr, *limit;
 		ext2_dirent *de;
-		struct page *page = ext2_get_page(inode, n);
+		struct page *page = ext2_get_page(inode, n, 0);
 
 		if (IS_ERR(page)) {
 			ext2_error(sb, __func__,
@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entr
 	struct page *page = NULL;
 	struct ext2_inode_info *ei = EXT2_I(dir);
 	ext2_dirent * de;
+	int dir_has_error = 0;
 
 	if (npages == 0)
 		goto out;
@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entr
 	n = start;
 	do {
 		char *kaddr;
-		page = ext2_get_page(dir, n);
+		page = ext2_get_page(dir, n, dir_has_error);
 		if (!IS_ERR(page)) {
 			kaddr = page_address(page);
 			de = (ext2_dirent *) kaddr;
@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entr
 				de = ext2_next_entry(de);
 			}
 			ext2_put_page(page);
-		}
+		} else
+			dir_has_error = 1;
+
 		if (++n >= npages)
 			n = 0;
 		/* next page is past the blocks we've got */
@@ -414,7 +421,7 @@ found:
 
 struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
 {
-	struct page *page = ext2_get_page(dir, 0);
+	struct page *page = ext2_get_page(dir, 0, 0);
 	ext2_dirent *de = NULL;
 
 	if (!IS_ERR(page)) {
@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry
 	for (n = 0; n <= npages; n++) {
 		char *dir_end;
 
-		page = ext2_get_page(dir, n);
+		page = ext2_get_page(dir, n, 0);
 		err = PTR_ERR(page);
 		if (IS_ERR(page))
 			goto out;
@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode
 {
 	struct page *page = NULL;
 	unsigned long i, npages = dir_pages(inode);
+	int dir_has_error = 0;
 
 	for (i = 0; i < npages; i++) {
 		char *kaddr;
 		ext2_dirent * de;
-		page = ext2_get_page(inode, i);
+		page = ext2_get_page(inode, i, dir_has_error);
 
-		if (IS_ERR(page))
+		if (IS_ERR(page)) {
+			dir_has_error = 1;
 			continue;
+		}
 
 		kaddr = page_address(page);
 		de = (ext2_dirent *)kaddr;
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * fi
 	int err;
 	struct inode *inode = filp->f_path.dentry->d_inode;
 	int ret = 0;
+	int dir_has_error = 0;
 
 	sb = inode->i_sb;
 
@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * fi
 		 * of recovering data when there's a bad sector
 		 */
 		if (!bh) {
-			ext3_error (sb, "ext3_readdir",
-				"directory #%lu contains a hole at offset %lu",
-				inode->i_ino, (unsigned long)filp->f_pos);
+			if (!dir_has_error) {
+				ext3_error(sb, __func__, "directory #%lu "
+					"contains a hole at offset %lld",
+					inode->i_ino, filp->f_pos);
+				dir_has_error = 1;
+			}
 			/* corrupt size?  Maybe no more blocks to read */
 			if (filp->f_pos > inode->i_blocks << 9)
 				break;
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -102,6 +102,7 @@ static int ext4_readdir(struct file * fi
 	int err;
 	struct inode *inode = filp->f_path.dentry->d_inode;
 	int ret = 0;
+	int dir_has_error = 0;
 
 	sb = inode->i_sb;
 
@@ -148,9 +149,13 @@ static int ext4_readdir(struct file * fi
 		 * of recovering data when there's a bad sector
 		 */
 		if (!bh) {
-			ext4_error (sb, "ext4_readdir",
-				"directory #%lu contains a hole at offset %lu",
-				inode->i_ino, (unsigned long)filp->f_pos);
+			if (!dir_has_error) {
+				ext4_error(sb, __func__, "directory #%lu "
+					   "contains a hole at offset %Lu",
+					   inode->i_ino,
+					   (unsigned long long) filp->f_pos);
+				dir_has_error = 1;
+			}
 			/* corrupt size?  Maybe no more blocks to read */
 			if (filp->f_pos > inode->i_blocks << 9)
 				break;

-- 

  parent reply	other threads:[~2008-10-24  4:39 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20081024042023.054190751@mini.kroah.org>
2008-10-24  4:33 ` [patch 00/27] 2.6.27.4-stable review Greg KH
2008-10-24  4:33   ` [patch 01/27] gpiolib: fix oops in gpio_get_value_cansleep() Greg KH
2008-10-24  4:33   ` [patch 02/27] edac cell: fix incorrect edac_mode Greg KH
2008-10-24  4:33   ` [patch 03/27] x86 ACPI: fix breakage of resume on 64-bit UP systems with SMP kernel Greg KH
2008-10-24  4:33   ` [patch 04/27] sched: fix the wrong mask_len Greg KH
2008-10-24  4:33   ` [patch 05/27] USB: cdc-wdm: make module autoload work Greg KH
2008-10-24  4:33   ` [patch 06/27] USB: dont rebind drivers after failed resume or reset Greg KH
2008-10-24  4:33   ` [patch 07/27] USB: fix memory leak in cdc-acm Greg KH
2008-10-24  4:34   ` [patch 08/27] USB: Speedtouch: add pre_reset and post_reset routines Greg KH
2008-10-24  4:34   ` [patch 09/27] dm kcopyd: avoid queue shuffle Greg KH
2008-10-24  4:34   ` [patch 10/27] dm snapshot: fix primary_pe race Greg KH
2008-10-24  4:34   ` [patch 11/27] dm exception store: refactor zero_area Greg KH
2008-10-24  5:36     ` Greg KH
2008-10-25  1:40       ` Mikulas Patocka
2008-10-25 20:28         ` Greg KH
2008-10-24  4:34   ` [patch 12/27] dm exception store: fix misordered writes Greg KH
2008-10-24  4:34   ` [patch 13/27] amd_iommu: fix nasty bug that caused ILLEGAL_DEVICE_TABLE_ENTRY errors Greg KH
2008-10-24  4:34   ` [patch 14/27] CIFS: fix saving of resume key before CIFSFindNext Greg KH
2008-10-24  4:34   ` Greg KH [this message]
2008-10-24  4:34   ` [patch 16/27] netfilter: xt_iprange: fix range inversion match Greg KH
2008-10-24  4:34   ` [patch 17/27] netfilter: snmp nat leaks memory in case of failure Greg KH
2008-10-24  4:34     ` Greg KH
2008-10-24  4:34   ` [patch 18/27] netfilter: restore lost ifdef guarding defrag exception Greg KH
2008-10-24  4:34   ` [patch 19/27] anon_vma_prepare: properly lock even newly allocated entries Greg KH
2008-10-24  4:34   ` [patch 20/27] hvc_console: Fix free_irq in spinlocked section Greg KH
2008-10-24  4:35   ` [patch 21/27] ACPI Suspend: Enable ACPI during resume if SCI_EN is not set Greg KH
2008-10-24  4:35   ` [patch 22/27] ACPI suspend: Blacklist HP xw4600 Workstation for old code ordering Greg KH
2008-10-24  4:35   ` [patch 23/27] ACPI suspend: Always use the 32-bit waking vector Greg KH
2008-10-24  4:35   ` [patch 24/27] proc: fix vma display mismatch between /proc/pid/{maps,smaps} Greg KH
2008-10-24  4:35   ` [patch 25/27] SCSI: scsi_dh: add Dell product information into rdac device handler Greg KH
2008-10-24  4:35   ` [patch 26/27] PCI hotplug: cpqphp: fix kernel NULL pointer dereference Greg KH
2008-10-24  4:35   ` [patch 27/27] ath5k: fix suspend-related oops on rmmod Greg KH
2008-10-24 20:36     ` Elias Oltmanns
2008-10-24 21:10       ` Bob Copeland
2008-10-24 21:28       ` Greg KH
2008-10-24  5:41   ` [patch 00/27] 2.6.27.4-stable review Greg KH
2008-10-24 21:38     ` [stable] " Greg KH
2008-10-24 21:40       ` [patch 28/27] V4L/DVB (9300): pvrusb2: Fix deadlock problem Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081024043437.GP30828@kroah.com \
    --to=gregkh@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=cavokz@gmail.com \
    --cc=cebbert@redhat.com \
    --cc=chuckw@quantumlinux.com \
    --cc=davej@redhat.com \
    --cc=eteo@redhat.com \
    --cc=eugeneteo@kernel.sg \
    --cc=jake@lwn.net \
    --cc=jmforbes@linuxtx.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mkrufky@linuxtv.org \
    --cc=rbranco@la.checkpoint.com \
    --cc=rdunlap@xenotime.net \
    --cc=reviews@ml.cw.f00f.org \
    --cc=sandeen@redhat.com \
    --cc=stable@kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=tytso@mit.edu \
    --cc=w@1wt.eu \
    --cc=zwane@arm.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.