summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_lockf.c
diff options
context:
space:
mode:
authoranton <anton@cvs.openbsd.org>2018-10-06 21:12:24 +0000
committeranton <anton@cvs.openbsd.org>2018-10-06 21:12:24 +0000
commit1cd322a8fcc70433e1e7eb8331dd23e3303e9fbe (patch)
tree978f54e94a02e15ccd73f36dcb1b771c32de046f /sys/kern/vfs_lockf.c
parent8a82d4fafcd86e36d85fe82f45922863e926d80f (diff)
When freeing a lockf struct that already is part of a linked list, make sure to
update the next pointer for the preceding lock. Prevents a double free panic. ok millert@
Diffstat (limited to 'sys/kern/vfs_lockf.c')
-rw-r--r--sys/kern/vfs_lockf.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/sys/kern/vfs_lockf.c b/sys/kern/vfs_lockf.c
index 9bd95aede32..edf6204782d 100644
--- a/sys/kern/vfs_lockf.c
+++ b/sys/kern/vfs_lockf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_lockf.c,v 1.25 2018/02/26 13:43:51 mpi Exp $ */
+/* $OpenBSD: vfs_lockf.c,v 1.26 2018/10/06 21:12:23 anton Exp $ */
/* $NetBSD: vfs_lockf.c,v 1.7 1996/02/04 02:18:21 christos Exp $ */
/*
@@ -352,6 +352,13 @@ lf_setlock(struct lockf *lock)
* Check for common starting point and different types.
*/
if (overlap->lf_type == lock->lf_type) {
+ /*
+ * If the lock about to be freed already is in
+ * the list, update the previous lock to point
+ * to the lock after the freed one.
+ */
+ if (!needtolink)
+ *prev = lock->lf_next;
lf_free(lock);
lock = overlap; /* for debug output below */
break;
@@ -401,7 +408,7 @@ lf_setlock(struct lockf *lock)
lock->lf_next = overlap->lf_next;
overlap->lf_next = lock;
overlap->lf_end = lock->lf_start - 1;
- prev = &lock->lf_next;
+ prev = &overlap->lf_next;
lf_wakelock(overlap);
needtolink = 0;
continue;