Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1075

kernel-2.6.18-238.el5.src.rpm

From: Anton Arapov <aarapov@redhat.com>
Date: Thu, 13 Nov 2008 16:08:48 +0100
Subject: [fs] hfsplus: check read_mapping_page return value
Message-id: 20081113150846.GC10438@redhat.com
O-Subject: [RHEL5.4 PATCH] BZ469645: CVE-2008-4934 kernel: hfsplus: check read_mapping_page() return value
Bugzilla: 469645
RH-Acked-by: Jiri Pirko <jpirko@redhat.com>
RH-Acked-by: Eugene Teo <eteo@redhat.com>
RH-Acked-by: John Feeney <jfeeney@redhat.com>
CVE: CVE-2008-4934

Bugzilla: 469645

Description:
  Return value of read_mapping_page() is passed on to kmap unchecked.
The bug is triggered after the first read_mapping_page()
in hfsplus_block_allocate(), this patch fixes all three usages in this
functions but leaves the ones further down in the file unchanged.

Upstream status:
  commit# 649f1ee6c705aab644035a7998d7b574193a598a

Test status:
  patched kernel has been successfuly built, tested for boot.
  hfsplus module successfully inserts and removes in/from kernel.
  https://brewweb.devel.redhat.com/taskinfo?taskID=1572109

Notice:
  CVE-2008-4934
  BZ469643 clone of this bug for RHEL4.8

==

diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c
index d128a25..ea30afc 100644
--- a/fs/hfsplus/bitmap.c
+++ b/fs/hfsplus/bitmap.c
@@ -32,6 +32,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
 	mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
 	mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
 	page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL);
+	if (IS_ERR(page)) {
+		start = size;
+		goto out;
+	}
 	pptr = kmap(page);
 	curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
 	i = offset % 32;
@@ -73,6 +77,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
 			break;
 		page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
 					 NULL);
+		if (IS_ERR(page)) {
+			start = size;
+			goto out;
+		}
 		curr = pptr = kmap(page);
 		if ((size ^ offset) / PAGE_CACHE_BITS)
 			end = pptr + PAGE_CACHE_BITS / 32;
@@ -120,6 +128,10 @@ found:
 		offset += PAGE_CACHE_BITS;
 		page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
 					 NULL);
+		if (IS_ERR(page)) {
+			start = size;
+			goto out;
+		}
 		pptr = kmap(page);
 		curr = pptr;
 		end = pptr + PAGE_CACHE_BITS / 32;