Commit f8de483e authored by David Howells's avatar David Howells

afs: Properly reset afs_vnode (inode) fields

When an AFS inode is allocated by afs_alloc_inode(), the allocated
afs_vnode struct isn't necessarily reset from the last time it was used as
an inode because the slab constructor is only invoked once when the memory
is obtained from the page allocator.

This means that information can leak from one inode to the next because
we're not calling kmem_cache_zalloc().  Some of the information isn't
reset, in particular the permit cache pointer.

Bring the clearances up to date.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Tested-by: default avatarMarc Dionne <marc.dionne@auristor.com>
parent 1bcab125
...@@ -441,7 +441,10 @@ enum afs_lock_state { ...@@ -441,7 +441,10 @@ enum afs_lock_state {
}; };
/* /*
* AFS inode private data * AFS inode private data.
*
* Note that afs_alloc_inode() *must* reset anything that could incorrectly
* leak from one inode to another.
*/ */
struct afs_vnode { struct afs_vnode {
struct inode vfs_inode; /* the VFS's inode record */ struct inode vfs_inode; /* the VFS's inode record */
......
...@@ -536,7 +536,9 @@ static void afs_kill_super(struct super_block *sb) ...@@ -536,7 +536,9 @@ static void afs_kill_super(struct super_block *sb)
} }
/* /*
* initialise an inode cache slab element prior to any use * Initialise an inode cache slab element prior to any use. Note that
* afs_alloc_inode() *must* reset anything that could incorrectly leak from one
* inode to another.
*/ */
static void afs_i_init_once(void *_vnode) static void afs_i_init_once(void *_vnode)
{ {
...@@ -568,11 +570,21 @@ static struct inode *afs_alloc_inode(struct super_block *sb) ...@@ -568,11 +570,21 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
atomic_inc(&afs_count_active_inodes); atomic_inc(&afs_count_active_inodes);
/* Reset anything that shouldn't leak from one inode to the next. */
memset(&vnode->fid, 0, sizeof(vnode->fid)); memset(&vnode->fid, 0, sizeof(vnode->fid));
memset(&vnode->status, 0, sizeof(vnode->status)); memset(&vnode->status, 0, sizeof(vnode->status));
vnode->volume = NULL; vnode->volume = NULL;
vnode->lock_key = NULL;
vnode->permit_cache = NULL;
vnode->cb_interest = NULL;
#ifdef CONFIG_AFS_FSCACHE
vnode->cache = NULL;
#endif
vnode->flags = 1 << AFS_VNODE_UNSET; vnode->flags = 1 << AFS_VNODE_UNSET;
vnode->cb_type = 0;
vnode->lock_state = AFS_VNODE_LOCK_NONE;
_leave(" = %p", &vnode->vfs_inode); _leave(" = %p", &vnode->vfs_inode);
return &vnode->vfs_inode; return &vnode->vfs_inode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment