aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-12-26 13:25:26 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-12-26 13:25:26 -0500
commit6d4b9e38d3980826abccfbd90e95bf4bd41b8dd2 (patch)
tree7473e333fc5aae6dd1d4b7f86205a330818518ce /fs
parent4962516b2309d76964f9df0d33e74f43b624a42d (diff)
vfs: fix handling of lock allocation failure in lease-break case
Bruce Fields notes that commit 778fc546f749 ("locks: fix tracking of inprogress lease breaks") introduced a possible error pointer dereference on failure to allocate memory. locks_conflict() will dereference the passed-in new lease lock structure that may be an error pointer. This means an open (without O_NONBLOCK set) on a file with a lease applied (generally only done when Samba or nfsd (with v4) is running) could crash if a kmalloc() fails. So instead of playing games with IS_ERROR() all over the place, just check the allocation failure early. That makes the code more straightforward, and avoids this possible bad pointer dereference. Based-on-patch-by: J. Bruce Fields <bfields@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/locks.c11
1 files changed, 3 insertions, 8 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 3b0d05dcd7c1..637694bf3a03 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1205,6 +1205,8 @@ int __break_lease(struct inode *inode, unsigned int mode)
1205 int want_write = (mode & O_ACCMODE) != O_RDONLY; 1205 int want_write = (mode & O_ACCMODE) != O_RDONLY;
1206 1206
1207 new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); 1207 new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
1208 if (IS_ERR(new_fl))
1209 return PTR_ERR(new_fl);
1208 1210
1209 lock_flocks(); 1211 lock_flocks();
1210 1212
@@ -1221,12 +1223,6 @@ int __break_lease(struct inode *inode, unsigned int mode)
1221 if (fl->fl_owner == current->files) 1223 if (fl->fl_owner == current->files)
1222 i_have_this_lease = 1; 1224 i_have_this_lease = 1;
1223 1225
1224 if (IS_ERR(new_fl) && !i_have_this_lease
1225 && ((mode & O_NONBLOCK) == 0)) {
1226 error = PTR_ERR(new_fl);
1227 goto out;
1228 }
1229
1230 break_time = 0; 1226 break_time = 0;
1231 if (lease_break_time > 0) { 1227 if (lease_break_time > 0) {
1232 break_time = jiffies + lease_break_time * HZ; 1228 break_time = jiffies + lease_break_time * HZ;
@@ -1284,8 +1280,7 @@ restart:
1284 1280
1285out: 1281out:
1286 unlock_flocks(); 1282 unlock_flocks();
1287 if (!IS_ERR(new_fl)) 1283 locks_free_lock(new_fl);
1288 locks_free_lock(new_fl);
1289 return error; 1284 return error;
1290} 1285}
1291 1286