Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGoldwyn Rodrigues <rgoldwyn@suse.de>2014-11-21 16:47:28 +0100
committerGoldwyn Rodrigues <rgoldwyn@suse.de>2014-11-21 16:47:28 +0100
commit4f07b1167f59ea2b4069aae6c367edfb68abb77e (patch)
tree82787e59a56c6fbcd37d8a7bdaf4e608faaf4099
parentc2cd2fcd33ba0e8d39a4358822019be162e0e11a (diff)
- ocfs2: fix NULL pointer dereference in ocfs2_duplicate_clusters_by_pagerpm-3.0.101-0.42
(bnc#899843). - Refresh patches.fixes/ocfs2-remove-filesize-checks-for-journal-commits.patch.
-rw-r--r--patches.fixes/ocfs2-fix-NULL-pointer-dereference-in-ocfs2_duplicate_clusters_by_page264
-rw-r--r--patches.fixes/ocfs2-remove-filesize-checks-for-journal-commits.patch2
-rw-r--r--series.conf1
3 files changed, 266 insertions, 1 deletions
diff --git a/patches.fixes/ocfs2-fix-NULL-pointer-dereference-in-ocfs2_duplicate_clusters_by_page b/patches.fixes/ocfs2-fix-NULL-pointer-dereference-in-ocfs2_duplicate_clusters_by_page
new file mode 100644
index 0000000000..26ddc717e2
--- /dev/null
+++ b/patches.fixes/ocfs2-fix-NULL-pointer-dereference-in-ocfs2_duplicate_clusters_by_page
@@ -0,0 +1,264 @@
+From: Tiger Yang <tiger.yang@oracle.com>
+Git-commit: c7dd3392ad469e6ba125170ad29f881bed85b678
+Date: Tue Aug 13 16:00:58 2013 -0700
+Patch-mainline: v3.11-rc6
+References: bnc#899843
+Subject: ocfs2: fix NULL pointer dereference in ocfs2_duplicate_clusters_by_page
+
+ Since ocfs2_cow_file_pos will invoke ocfs2_refcount_icow with a NULL as
+ the struct file pointer, it finally result in a null pointer dereference
+ in ocfs2_duplicate_clusters_by_page.
+
+ This patch replace file pointer with inode pointer in
+ cow_duplicate_clusters to fix this issue.
+
+ [jeff.liu@oracle.com: rebased patch against linux-next tree]
+ Signed-off-by: Tiger Yang <tiger.yang@oracle.com>
+ Signed-off-by: Jie Liu <jeff.liu@oracle.com>
+ Cc: Joel Becker <jlbec@evilplan.org>
+ Cc: Mark Fasheh <mfasheh@suse.com>
+ Acked-by: Tao Ma <tm@tao.ma>
+ Tested-by: David Weber <wb@munzinger.de>
+ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+ Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
+
+Index: linux-3.0-SLE11-SP3/fs/ocfs2/aops.c
+===================================================================
+--- linux-3.0-SLE11-SP3.orig/fs/ocfs2/aops.c
++++ linux-3.0-SLE11-SP3/fs/ocfs2/aops.c
+@@ -1735,7 +1735,7 @@ try_again:
+ goto out;
+ } else if (ret == 1) {
+ clusters_need = wc->w_clen;
+- ret = ocfs2_refcount_cow(inode, filp, di_bh,
++ ret = ocfs2_refcount_cow(inode, di_bh,
+ wc->w_cpos, wc->w_clen, UINT_MAX);
+ if (ret) {
+ mlog_errno(ret);
+Index: linux-3.0-SLE11-SP3/fs/ocfs2/file.c
+===================================================================
+--- linux-3.0-SLE11-SP3.orig/fs/ocfs2/file.c
++++ linux-3.0-SLE11-SP3/fs/ocfs2/file.c
+@@ -370,7 +370,7 @@ static int ocfs2_cow_file_pos(struct ino
+ if (!(ext_flags & OCFS2_EXT_REFCOUNTED))
+ goto out;
+
+- return ocfs2_refcount_cow(inode, NULL, fe_bh, cpos, 1, cpos+1);
++ return ocfs2_refcount_cow(inode, fe_bh, cpos, 1, cpos+1);
+
+ out:
+ return status;
+@@ -899,7 +899,7 @@ static int ocfs2_zero_extend_get_range(s
+ zero_clusters = last_cpos - zero_cpos;
+
+ if (needs_cow) {
+- rc = ocfs2_refcount_cow(inode, NULL, di_bh, zero_cpos,
++ rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos,
+ zero_clusters, UINT_MAX);
+ if (rc) {
+ mlog_errno(rc);
+@@ -2086,7 +2086,7 @@ static int ocfs2_prepare_inode_for_refco
+
+ *meta_level = 1;
+
+- ret = ocfs2_refcount_cow(inode, file, di_bh, cpos, clusters, UINT_MAX);
++ ret = ocfs2_refcount_cow(inode, di_bh, cpos, clusters, UINT_MAX);
+ if (ret)
+ mlog_errno(ret);
+ out:
+Index: linux-3.0-SLE11-SP3/fs/ocfs2/move_extents.c
+===================================================================
+--- linux-3.0-SLE11-SP3.orig/fs/ocfs2/move_extents.c
++++ linux-3.0-SLE11-SP3/fs/ocfs2/move_extents.c
+@@ -70,7 +70,7 @@ static int __ocfs2_move_extent(handle_t
+ u64 ino = ocfs2_metadata_cache_owner(context->et.et_ci);
+ u64 old_blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cpos);
+
+- ret = ocfs2_duplicate_clusters_by_page(handle, context->file, cpos,
++ ret = ocfs2_duplicate_clusters_by_page(handle, inode, cpos,
+ p_cpos, new_p_cpos, len);
+ if (ret) {
+ mlog_errno(ret);
+Index: linux-3.0-SLE11-SP3/fs/ocfs2/refcounttree.c
+===================================================================
+--- linux-3.0-SLE11-SP3.orig/fs/ocfs2/refcounttree.c
++++ linux-3.0-SLE11-SP3/fs/ocfs2/refcounttree.c
+@@ -49,7 +49,6 @@
+
+ struct ocfs2_cow_context {
+ struct inode *inode;
+- struct file *file;
+ u32 cow_start;
+ u32 cow_len;
+ struct ocfs2_extent_tree data_et;
+@@ -66,7 +65,7 @@ struct ocfs2_cow_context {
+ u32 *num_clusters,
+ unsigned int *extent_flags);
+ int (*cow_duplicate_clusters)(handle_t *handle,
+- struct file *file,
++ struct inode *inode,
+ u32 cpos, u32 old_cluster,
+ u32 new_cluster, u32 new_len);
+ };
+@@ -2922,14 +2921,12 @@ static int ocfs2_clear_cow_buffer(handle
+ }
+
+ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
+- struct file *file,
++ struct inode *inode,
+ u32 cpos, u32 old_cluster,
+ u32 new_cluster, u32 new_len)
+ {
+ int ret = 0, partial;
+- struct inode *inode = file->f_path.dentry->d_inode;
+- struct ocfs2_caching_info *ci = INODE_CACHE(inode);
+- struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
++ struct super_block *sb = inode->i_sb;
+ u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster);
+ struct page *page;
+ pgoff_t page_index;
+@@ -2973,13 +2970,6 @@ int ocfs2_duplicate_clusters_by_page(han
+ if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize)
+ BUG_ON(PageDirty(page));
+
+- if (PageReadahead(page)) {
+- page_cache_async_readahead(mapping,
+- &file->f_ra, file,
+- page, page_index,
+- readahead_pages);
+- }
+-
+ if (!PageUptodate(page)) {
+ ret = block_read_full_page(page, ocfs2_get_block);
+ if (ret) {
+@@ -2999,7 +2989,8 @@ int ocfs2_duplicate_clusters_by_page(han
+ }
+ }
+
+- ocfs2_map_and_dirty_page(inode, handle, from, to,
++ ocfs2_map_and_dirty_page(inode,
++ handle, from, to,
+ page, 0, &new_block);
+ mark_page_accessed(page);
+ unlock:
+@@ -3015,12 +3006,11 @@ unlock:
+ }
+
+ int ocfs2_duplicate_clusters_by_jbd(handle_t *handle,
+- struct file *file,
++ struct inode *inode,
+ u32 cpos, u32 old_cluster,
+ u32 new_cluster, u32 new_len)
+ {
+ int ret = 0;
+- struct inode *inode = file->f_path.dentry->d_inode;
+ struct super_block *sb = inode->i_sb;
+ struct ocfs2_caching_info *ci = INODE_CACHE(inode);
+ int i, blocks = ocfs2_clusters_to_blocks(sb, new_len);
+@@ -3145,7 +3135,7 @@ static int ocfs2_replace_clusters(handle
+
+ /*If the old clusters is unwritten, no need to duplicate. */
+ if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) {
+- ret = context->cow_duplicate_clusters(handle, context->file,
++ ret = context->cow_duplicate_clusters(handle, context->inode,
+ cpos, old, new, len);
+ if (ret) {
+ mlog_errno(ret);
+@@ -3423,35 +3413,12 @@ static int ocfs2_replace_cow(struct ocfs
+ return ret;
+ }
+
+-static void ocfs2_readahead_for_cow(struct inode *inode,
+- struct file *file,
+- u32 start, u32 len)
+-{
+- struct address_space *mapping;
+- pgoff_t index;
+- unsigned long num_pages;
+- int cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits;
+-
+- if (!file)
+- return;
+-
+- mapping = file->f_mapping;
+- num_pages = (len << cs_bits) >> PAGE_CACHE_SHIFT;
+- if (!num_pages)
+- num_pages = 1;
+-
+- index = ((loff_t)start << cs_bits) >> PAGE_CACHE_SHIFT;
+- page_cache_sync_readahead(mapping, &file->f_ra, file,
+- index, num_pages);
+-}
+-
+ /*
+ * Starting at cpos, try to CoW write_len clusters. Don't CoW
+ * past max_cpos. This will stop when it runs into a hole or an
+ * unrefcounted extent.
+ */
+ static int ocfs2_refcount_cow_hunk(struct inode *inode,
+- struct file *file,
+ struct buffer_head *di_bh,
+ u32 cpos, u32 write_len, u32 max_cpos)
+ {
+@@ -3480,8 +3447,6 @@ static int ocfs2_refcount_cow_hunk(struc
+
+ BUG_ON(cow_len == 0);
+
+- ocfs2_readahead_for_cow(inode, file, cow_start, cow_len);
+-
+ context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS);
+ if (!context) {
+ ret = -ENOMEM;
+@@ -3503,7 +3468,6 @@ static int ocfs2_refcount_cow_hunk(struc
+ context->ref_root_bh = ref_root_bh;
+ context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page;
+ context->get_clusters = ocfs2_di_get_clusters;
+- context->file = file;
+
+ ocfs2_init_dinode_extent_tree(&context->data_et,
+ INODE_CACHE(inode), di_bh);
+@@ -3532,7 +3496,6 @@ out:
+ * clusters between cpos and cpos+write_len are safe to modify.
+ */
+ int ocfs2_refcount_cow(struct inode *inode,
+- struct file *file,
+ struct buffer_head *di_bh,
+ u32 cpos, u32 write_len, u32 max_cpos)
+ {
+@@ -3552,7 +3515,7 @@ int ocfs2_refcount_cow(struct inode *ino
+ num_clusters = write_len;
+
+ if (ext_flags & OCFS2_EXT_REFCOUNTED) {
+- ret = ocfs2_refcount_cow_hunk(inode, file, di_bh, cpos,
++ ret = ocfs2_refcount_cow_hunk(inode, di_bh, cpos,
+ num_clusters, max_cpos);
+ if (ret) {
+ mlog_errno(ret);
+Index: linux-3.0-SLE11-SP3/fs/ocfs2/refcounttree.h
+===================================================================
+--- linux-3.0-SLE11-SP3.orig/fs/ocfs2/refcounttree.h
++++ linux-3.0-SLE11-SP3/fs/ocfs2/refcounttree.h
+@@ -53,7 +53,7 @@ int ocfs2_prepare_refcount_change_for_de
+ int *credits,
+ int *ref_blocks);
+ int ocfs2_refcount_cow(struct inode *inode,
+- struct file *filep, struct buffer_head *di_bh,
++ struct buffer_head *di_bh,
+ u32 cpos, u32 write_len, u32 max_cpos);
+
+ typedef int (ocfs2_post_refcount_func)(struct inode *inode,
+@@ -85,11 +85,11 @@ int ocfs2_refcount_cow_xattr(struct inod
+ u32 cpos, u32 write_len,
+ struct ocfs2_post_refcount *post);
+ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
+- struct file *file,
++ struct inode *inode,
+ u32 cpos, u32 old_cluster,
+ u32 new_cluster, u32 new_len);
+ int ocfs2_duplicate_clusters_by_jbd(handle_t *handle,
+- struct file *file,
++ struct inode *inode,
+ u32 cpos, u32 old_cluster,
+ u32 new_cluster, u32 new_len);
+ int ocfs2_cow_sync_writeback(struct super_block *sb,
diff --git a/patches.fixes/ocfs2-remove-filesize-checks-for-journal-commits.patch b/patches.fixes/ocfs2-remove-filesize-checks-for-journal-commits.patch
index 36f00f033e..eea6a7aa34 100644
--- a/patches.fixes/ocfs2-remove-filesize-checks-for-journal-commits.patch
+++ b/patches.fixes/ocfs2-remove-filesize-checks-for-journal-commits.patch
@@ -1,7 +1,7 @@
From: Goldwyn Rodrigues <rgoldwyn@suse.com>
Subject: [PATCH] Remove filesize checks for sync I/O journal commit
References: bnc#800255
-Patch-mainline: Yes, in -next tree
+Patch-mainline: next-20141121
Filesize is not a good indication that the file needs to be synced.
An example where this breaks is:
diff --git a/series.conf b/series.conf
index f0379a9b27..8b02dacd52 100644
--- a/series.conf
+++ b/series.conf
@@ -3698,6 +3698,7 @@
patches.fixes/o2dlm-fix-NULL-pointer-dereference-in-o2dlm_blocking_ast_wrapper
patches.fixes/ocfs2-remove-unnecssary-error-while-rm-non-empty-dirs.patch
patches.fixes/ocfs2-remove-filesize-checks-for-journal-commits.patch
+ patches.fixes/ocfs2-fix-NULL-pointer-dereference-in-ocfs2_duplicate_clusters_by_page
########################################################
# gfs2 read-only support for migration