Skip to content

Commit

Permalink
fs: fix lock initialization
Browse files Browse the repository at this point in the history
locks_alloc_lock() assumed that the allocated struct file_lock is
already initialized to zero members.  This is only true for the first
allocation of the structure, after reuse some of the members will have
random values.

This will for example result in passing random fl_start values to
userspace in fuse for FL_FLOCK locks, which is an information leak at
best.

Fix by reinitializing those members which may be non-zero after freeing.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
CC: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Miklos Szeredi authored and Linus Torvalds committed Jul 6, 2011
1 parent a2fa83f commit a51cb91
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions fs/locks.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,28 @@ EXPORT_SYMBOL_GPL(unlock_flocks);

static struct kmem_cache *filelock_cache __read_mostly;

static void locks_init_lock_always(struct file_lock *fl)
{
fl->fl_next = NULL;
fl->fl_fasync = NULL;
fl->fl_owner = NULL;
fl->fl_pid = 0;
fl->fl_nspid = NULL;
fl->fl_file = NULL;
fl->fl_flags = 0;
fl->fl_type = 0;
fl->fl_start = fl->fl_end = 0;
}

/* Allocate an empty lock structure. */
struct file_lock *locks_alloc_lock(void)
{
return kmem_cache_alloc(filelock_cache, GFP_KERNEL);
struct file_lock *fl = kmem_cache_alloc(filelock_cache, GFP_KERNEL);

if (fl)
locks_init_lock_always(fl);

return fl;
}
EXPORT_SYMBOL_GPL(locks_alloc_lock);

Expand Down Expand Up @@ -200,17 +218,9 @@ void locks_init_lock(struct file_lock *fl)
INIT_LIST_HEAD(&fl->fl_link);
INIT_LIST_HEAD(&fl->fl_block);
init_waitqueue_head(&fl->fl_wait);
fl->fl_next = NULL;
fl->fl_fasync = NULL;
fl->fl_owner = NULL;
fl->fl_pid = 0;
fl->fl_nspid = NULL;
fl->fl_file = NULL;
fl->fl_flags = 0;
fl->fl_type = 0;
fl->fl_start = fl->fl_end = 0;
fl->fl_ops = NULL;
fl->fl_lmops = NULL;
locks_init_lock_always(fl);
}

EXPORT_SYMBOL(locks_init_lock);
Expand Down

0 comments on commit a51cb91

Please sign in to comment.