Skip to content

Commit a51cb91

Browse files
Miklos Szereditorvalds
authored andcommitted
fs: fix lock initialization
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 <[email protected]> CC: [email protected] Signed-off-by: Linus Torvalds <[email protected]>
1 parent a2fa83f commit a51cb91

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

fs/locks.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,28 @@ EXPORT_SYMBOL_GPL(unlock_flocks);
160160

161161
static struct kmem_cache *filelock_cache __read_mostly;
162162

163+
static void locks_init_lock_always(struct file_lock *fl)
164+
{
165+
fl->fl_next = NULL;
166+
fl->fl_fasync = NULL;
167+
fl->fl_owner = NULL;
168+
fl->fl_pid = 0;
169+
fl->fl_nspid = NULL;
170+
fl->fl_file = NULL;
171+
fl->fl_flags = 0;
172+
fl->fl_type = 0;
173+
fl->fl_start = fl->fl_end = 0;
174+
}
175+
163176
/* Allocate an empty lock structure. */
164177
struct file_lock *locks_alloc_lock(void)
165178
{
166-
return kmem_cache_alloc(filelock_cache, GFP_KERNEL);
179+
struct file_lock *fl = kmem_cache_alloc(filelock_cache, GFP_KERNEL);
180+
181+
if (fl)
182+
locks_init_lock_always(fl);
183+
184+
return fl;
167185
}
168186
EXPORT_SYMBOL_GPL(locks_alloc_lock);
169187

@@ -200,17 +218,9 @@ void locks_init_lock(struct file_lock *fl)
200218
INIT_LIST_HEAD(&fl->fl_link);
201219
INIT_LIST_HEAD(&fl->fl_block);
202220
init_waitqueue_head(&fl->fl_wait);
203-
fl->fl_next = NULL;
204-
fl->fl_fasync = NULL;
205-
fl->fl_owner = NULL;
206-
fl->fl_pid = 0;
207-
fl->fl_nspid = NULL;
208-
fl->fl_file = NULL;
209-
fl->fl_flags = 0;
210-
fl->fl_type = 0;
211-
fl->fl_start = fl->fl_end = 0;
212221
fl->fl_ops = NULL;
213222
fl->fl_lmops = NULL;
223+
locks_init_lock_always(fl);
214224
}
215225

216226
EXPORT_SYMBOL(locks_init_lock);

0 commit comments

Comments
 (0)