aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/svclock.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@citi.umich.edu>2006-03-20 13:44:26 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:26 -0500
commit8dc7c3115b611c00006eac3ee5b108296432aab7 (patch)
treebe44c59907cbdcb6fdf46d0ad9cc140af757acfc /fs/lockd/svclock.c
parent2e0af86f618c697b44e2d67dff151256c58201c4 (diff)
locks,lockd: fix race in nlmsvc_testlock
posix_test_lock() returns a pointer to a struct file_lock which is unprotected and can be removed while in use by the caller. Move the conflicting lock from the return to a parameter, and copy the conflicting lock. In most cases the caller ends up putting the copy of the conflicting lock on the stack. On i386, sizeof(struct file_lock) appears to be about 100 bytes. We're assuming that's reasonable. Signed-off-by: Andy Adamson <andros@citi.umich.edu> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/lockd/svclock.c')
-rw-r--r--fs/lockd/svclock.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index f5398097b84b..d683dd022e08 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -376,8 +376,6 @@ u32
376nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock, 376nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
377 struct nlm_lock *conflock) 377 struct nlm_lock *conflock)
378{ 378{
379 struct file_lock *fl;
380
381 dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", 379 dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
382 file->f_file->f_dentry->d_inode->i_sb->s_id, 380 file->f_file->f_dentry->d_inode->i_sb->s_id,
383 file->f_file->f_dentry->d_inode->i_ino, 381 file->f_file->f_dentry->d_inode->i_ino,
@@ -385,14 +383,14 @@ nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
385 (long long)lock->fl.fl_start, 383 (long long)lock->fl.fl_start,
386 (long long)lock->fl.fl_end); 384 (long long)lock->fl.fl_end);
387 385
388 if ((fl = posix_test_lock(file->f_file, &lock->fl)) != NULL) { 386 if (posix_test_lock(file->f_file, &lock->fl, &conflock->fl)) {
389 dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n", 387 dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
390 fl->fl_type, (long long)fl->fl_start, 388 conflock->fl.fl_type,
391 (long long)fl->fl_end); 389 (long long)conflock->fl.fl_start,
390 (long long)conflock->fl.fl_end);
392 conflock->caller = "somehost"; /* FIXME */ 391 conflock->caller = "somehost"; /* FIXME */
393 conflock->oh.len = 0; /* don't return OH info */ 392 conflock->oh.len = 0; /* don't return OH info */
394 conflock->svid = fl->fl_pid; 393 conflock->svid = conflock->fl.fl_pid;
395 conflock->fl = *fl;
396 return nlm_lck_denied; 394 return nlm_lck_denied;
397 } 395 }
398 396