reiser4: fix null pointer dereference in reiser4_write_extent
PATCH 1/1 reiser4: fix null pointer dereference in reiser4_write_extent
Andrew, please apply.
Thanks,
Edward.
Problem:
Oops when starting kde4:
BUG: unable to handle kernel NULL pointer dereference at virtual address 0000000c printing eip: c025eba5 *pde = 00000000 Oops: 0000 [#1] SMP last sysfs file: /devices/pci0000:00/0000:00:1e.0/0000:04:04.0/resource Modules linked in: thermal processor fan button
Pid: 3705, comm: kwrite Not tainted (2.6.23-mm1 #8)
EIP: 0060:[<c025eba5>] EFLAGS: 00010246 CPU: 0 EIP is at update_extents+0x44/0x2e7
Bug:
Trying to look at not persistent struct file in the case of expanded truncate via sys_truncate64(path, length).
The fixup:
. Don't look at struct file at truncate_file_body(); . Add an inode *inode argument to the following
functions to handle the case of not persistent struct file.
. reiser4_write_extent();
. reiser4_write_tail();
. reiser4_update_extents();
Other changes:
. Add missesd identifier in some asserts.
. Comments cleanups.
--- linux-2.6.24-rc8-mm1/fs/reiser4/plugin/file/cryptcompress.c | 8 linux-2.6.24-rc8-mm1/fs/reiser4/plugin/file/file.c | 115 +++++----- linux-2.6.24-rc8-mm1/fs/reiser4/plugin/file/file.h | 8 linux-2.6.24-rc8-mm1/fs/reiser4/plugin/file/tail_conversion.c | 2 linux-2.6.24-rc8-mm1/fs/reiser4/plugin/item/extent.h | 4 linux-2.6.24-rc8-mm1/fs/reiser4/plugin/item/extent_file_ops.c | 15 - linux-2.6.24-rc8-mm1/fs/reiser4/plugin/item/item.h | 3 linux-2.6.24-rc8-mm1/fs/reiser4/plugin/item/tail.c | 9 linux-2.6.24-rc8-mm1/fs/reiser4/plugin/item/tail.h | 4 9 files changed, 86 insertions(+), 82 deletions(-)
fs/reiser4/plugin/file/cryptcompress.c renamed from fs/reiser4/plugin/file/cryptcompress.c.orig +4 -4
@@ -3198,11 +3198,11 @@return result; } -static int -update_cryptcompress_size (struct inode *inode,reiser4_key * key,int update_sd) +static int update_cryptcompress_size (struct inode *inode,loff_t new_size, +int update_sd) { -return (get_key_offset (key) & ((loff_t) (inode_cluster_size (inode)) -1 ) - ?0 :reiser4_update_file_size (inode, key, update_sd)); +return (new_size & ((loff_t) (inode_cluster_size (inode)) -1 ) + ?0 :reiser4_update_file_size (inode, new_size, update_sd)); }/* Prune cryptcompress file in two steps:
fs/reiser4/plugin/file/file.c renamed from fs/reiser4/plugin/file/file.c.orig +61 -54
239 lines not on this page · raw message
fs/reiser4/plugin/file/file.h renamed from fs/reiser4/plugin/file/file.h.orig +4 -4
@@ -280,10 +280,10 @@int hint_is_set (const hint_t *);void reiser4_unset_hint (hint_t *); -int reiser4_update_file_size (struct inode *,reiser4_key *,int update_sd); -int cut_file_items (struct inode *,loff_t new_size,int update_sd, -loff_t cur_size,int (*update_actor) (struct inode *, -reiser4_key *,int )); +int reiser4_update_file_size (struct inode *,loff_t ,int update_sd); +int cut_file_items (struct inode *,loff_t new_size, +int update_sd,loff_t cur_size, +int (*update_actor) (struct inode *,loff_t ,int ));#if REISER4_DEBUG /* return 1 is exclusive access is obtained, 0 - otherwise */
fs/reiser4/plugin/file/tail_conversion.c renamed from fs/reiser4/plugin/file/tail_conversion.c.orig +1 -1
@@ -651,7 +651,7 @@assert ("edward-1538" , file->f_dentry->d_inode == inode); - result =reiser4_write_tail (file, + result =reiser4_write_tail (file, inode, (char __user *)kmap (page), count, &pos);reiser4_free_file_fsdata (file);
fs/reiser4/plugin/item/extent.h renamed from fs/reiser4/plugin/item/extent.h.orig +2 -2
@@ -131,8 +131,8 @@int reiser4_check_extent (const coord_t * coord,const char **error);/* plugin->u.item.s.file.* */ -ssize_t reiser4_write_extent (struct file *,const char __user *, -size_t ,loff_t *); +ssize_t reiser4_write_extent (struct file *,struct inode * inode, +const char __user *,size_t ,loff_t *);int reiser4_read_extent (struct file *,flow_t *,hint_t *);int reiser4_readpage_extent (void *,struct page *);int reiser4_do_readpage_extent (reiser4_extent *,reiser4_block_nr ,struct page *);
fs/reiser4/plugin/item/extent_file_ops.c renamed from fs/reiser4/plugin/item/extent_file_ops.c.orig +6 -9
@@ -814,9 +814,9 @@* @off: * */ -static int update_extents (struct file *file,jnode **jnodes,int count,loff_t pos) +static int update_extents (struct file *file,struct inode *inode, +jnode **jnodes,int count,loff_t pos) { -struct inode *inode;struct hint hint;reiser4_key key;int result;
@@ -825,7 +825,6 @@ result =load_file_hint (file, &hint);BUG_ON (result !=0 ); - inode = file->f_dentry->d_inode;if (count !=0 )/* * count == 0 is special case: expanding truncate
@@ -969,14 +968,13 @@* @pos: position in file to write to * */ -ssize_t reiser4_write_extent (struct file *file,const char __user *buf, -size_t count,loff_t *pos) +ssize_t reiser4_write_extent (struct file *file,struct inode * inode, +const char __user *buf,size_t count,loff_t *pos) {int have_to_update_extent;int nr_pages, nr_dirty;struct page *page;jnode *jnodes[WRITE_GRANULARITY +1 ]; -struct inode *inode;unsigned long index;unsigned long end;int i;
@@ -984,13 +982,12 @@size_t left, written;int result =0 ; - inode = file->f_dentry->d_inode;if (write_extent_reserve_space (inode))return RETERR (-ENOSPC );if (count ==0 ) {/* truncate case */ -update_extents (file, jnodes,0 , *pos); +update_extents (file, inode, jnodes,0 , *pos);return 0 ; }
@@ -1090,7 +1087,7 @@ }if (have_to_update_extent) { -update_extents (file, jnodes, nr_dirty, *pos); +update_extents (file, inode, jnodes, nr_dirty, *pos); }else {for (i =0 ; i < nr_dirty; i ++) {int ret;
fs/reiser4/plugin/item/item.h renamed from fs/reiser4/plugin/item/item.h.orig +2 -1
@@ -233,7 +233,8 @@/* operations specific to items regular (unix) file metadata are built of */ struct file_iops { -int (*write) (struct file *,const char __user *,size_t ,loff_t *pos); +int (*write) (struct file *,struct inode *, +const char __user *,size_t ,loff_t *pos);int (*read) (struct file *,flow_t *,hint_t *);int (*readpage) (void *,struct page *);int (*get_block) (const coord_t *,sector_t ,sector_t *);
fs/reiser4/plugin/item/tail.c renamed from fs/reiser4/plugin/item/tail.c.orig +4 -5
@@ -626,7 +626,7 @@ }/** -* reiser4_write_extent - write method of tail item plugin +* reiser4_write_tail - write method of tail item plugin * @file: file to write to * @buf: address of user-space buffer * @count: number of bytes to write
@@ -634,10 +634,9 @@* * Returns number of written bytes or error code. */ -ssize_t reiser4_write_tail (struct file *file,const char __user *buf, -size_t count,loff_t *pos) +ssize_t reiser4_write_tail (struct file *file,struct inode * inode, +const char __user *buf,size_t count,loff_t *pos) { -struct inode *inode;struct hint hint;int result;flow_t flow;
@@ -645,7 +644,7 @@lock_handle *lh;znode *loaded; - inode = file->f_dentry->d_inode; +assert ("edward-1548" , inode !=NULL );if (write_extent_reserve_space (inode))return RETERR (-ENOSPC );
fs/reiser4/plugin/item/tail.h renamed from fs/reiser4/plugin/item/tail.h.orig +2 -2
@@ -33,8 +33,8 @@reiser4_key *unit_key_tail (const coord_t *,reiser4_key *);/* plugin->u.item.s.* */ -ssize_t reiser4_write_tail (struct file *file,const char __user *buf, -size_t count,loff_t *pos); +ssize_t reiser4_write_tail (struct file *file,struct inode * inode, +const char __user *buf,size_t count,loff_t *pos);int reiser4_read_tail (struct file *,flow_t *,hint_t *);int readpage_tail (void *vp,struct page *page);reiser4_key *append_key_tail (const coord_t *,reiser4_key *);