rpms/kernel/F-9 linux-2.6.26-ext-dir-corruption-fix.patch, NONE, 1.1 kernel.spec, 1.808, 1.809
Eric Sandeen
sandeen at fedoraproject.org
Wed Oct 22 15:52:58 UTC 2008
Author: sandeen
Update of /cvs/pkgs/rpms/kernel/F-9
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv8062
Modified Files:
kernel.spec
Added Files:
linux-2.6.26-ext-dir-corruption-fix.patch
Log Message:
* Wed Oct 22 2008 Eric Sandeen <sandeen at redhat.com>
- Patch for CVE-2008-3528, ext-fs dir corruption.
linux-2.6.26-ext-dir-corruption-fix.patch:
--- NEW FILE linux-2.6.26-ext-dir-corruption-fix.patch ---
Index: linux-2.6.26.noarch/fs/ext4/dir.c
===================================================================
--- linux-2.6.26.noarch.orig/fs/ext4/dir.c 2008-07-13 16:51:29.000000000 -0500
+++ linux-2.6.26.noarch/fs/ext4/dir.c 2008-10-22 10:47:12.367063504 -0500
@@ -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;
@@ -147,9 +148,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;
Index: linux-2.6.26.noarch/fs/ext2/dir.c
===================================================================
--- linux-2.6.26.noarch.orig/fs/ext2/dir.c 2008-07-13 16:51:29.000000000 -0500
+++ linux-2.6.26.noarch/fs/ext2/dir.c 2008-10-22 10:47:23.657063801 -0500
@@ -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;
Index: linux-2.6.26.noarch/fs/ext3/dir.c
===================================================================
--- linux-2.6.26.noarch.orig/fs/ext3/dir.c 2008-07-13 16:51:29.000000000 -0500
+++ linux-2.6.26.noarch/fs/ext3/dir.c 2008-10-22 10:47:33.466001682 -0500
@@ -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;
Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-9/kernel.spec,v
retrieving revision 1.808
retrieving revision 1.809
diff -u -r1.808 -r1.809
--- kernel.spec 21 Oct 2008 17:01:52 -0000 1.808
+++ kernel.spec 22 Oct 2008 15:52:25 -0000 1.809
@@ -734,6 +734,9 @@
# fix IOCTL security in sbni driver
Patch3100: linux-2.6-wan-missing-capability-checks-in-sbni_ioctl.patch
+# CVE-2008-3528
+Patch3200: linux-2.6.26-ext-dir-corruption-fix.patch
+
%endif
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1293,8 +1296,8 @@
ApplyPatch drm-fedora9-rollup.patch
ApplyPatch linux-2.6-drm-i915-fix-ioctl-security.patch
-# ext4dev stable patch queue, slated for 2.6.25
-#ApplyPatch linux-2.6-ext4-stable-queue.patch
+# Filesystem patches
+ApplyPatch linux-2.6.26-ext-dir-corruption-fix.patch
# linux1394 git patches
ApplyPatch linux-2.6-firewire-git-update.patch
@@ -1920,6 +1923,9 @@
%kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL}.xen -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.xen.conf %{with_xen} xen
%changelog
+* Wed Oct 22 2008 Eric Sandeen <sandeen at redhat.com>
+- Patch for CVE-2008-3528, ext-fs dir corruption.
+
* Tue Oct 21 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.26.7-81.rc1
- 2.6.26.7-rc1
Dropped patches:
More information about the scm-commits
mailing list