untrusted comment: verify with openbsd-64-base.pub
RWQq6XmS4eDAcWbOz93Dlq9QLLAVmAdzUopJGlnCg+mpqd3m5bE8lCH0EESJCAjmYe6UL69UiEaq1TOtVQU2ZVAjH0ozNsLlWQA=

OpenBSD 6.4 errata 004, November 17, 2018:

A recent change to POSIX file locks could cause incorrect results during
lock acquisition.

Apply by doing:
    signify -Vep /etc/signify/openbsd-64-base.pub -x 004_lockf.patch.sig \
        -m - | (cd /usr/src && patch -p0)

And then rebuild and install a new kernel:
    KK=`sysctl -n kern.osversion | cut -d# -f1`
    cd /usr/src/sys/arch/`machine`/compile/$KK
    make obj
    make config
    make
    make install

Index: sys/kern/vfs_lockf.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_lockf.c,v
retrieving revision 1.26
diff -u -p -r1.26 vfs_lockf.c
--- sys/kern/vfs_lockf.c	6 Oct 2018 21:12:23 -0000	1.26
+++ sys/kern/vfs_lockf.c	12 Nov 2018 19:12:01 -0000
@@ -122,12 +122,49 @@ lf_free(struct lockf *lock)
 {
 	struct uidinfo *uip;
 
+	if (*lock->lf_head == lock) {
+		*lock->lf_head = lock->lf_next;
+	}
+
+	lf_unlink(lock);
+
 	uip = uid_find(lock->lf_uid);
 	uip->ui_lockcnt--;
 	uid_release(uip);
 	pool_put(&lockfpool, lock);
 }
 
+void
+lf_link(struct lockf *lock1, struct lockf *lock2)
+{
+	if (lock1->lf_next != NULL) {
+		lock2->lf_next = lock1->lf_next;
+		lock1->lf_next->lf_prev = lock2;
+	}
+	lock1->lf_next = lock2;
+
+	if (lock2->lf_prev != NULL) {
+		lock1->lf_prev = lock2->lf_prev;
+		lock2->lf_prev->lf_next = lock1;
+	}
+	lock2->lf_prev = lock1;
+
+	if (*lock1->lf_head == NULL) {
+		*lock1->lf_head = lock1;
+	} else if (*lock2->lf_head == lock2) {
+		*lock1->lf_head = lock1;
+	}
+}
+
+void
+lf_unlink(struct lockf *lock)
+{
+	if (lock->lf_prev != NULL)
+		lock->lf_prev->lf_next = lock->lf_next;
+	if (lock->lf_next != NULL)
+		lock->lf_next->lf_prev = lock->lf_prev;
+	lock->lf_prev = lock->lf_next = NULL;
+}
 
 /*
  * Do an advisory lock operation.
@@ -187,6 +224,7 @@ lf_advlock(struct lockf **head, off_t si
 	lock->lf_id = id;
 	lock->lf_head = head;
 	lock->lf_type = fl->l_type;
+	lock->lf_prev = NULL;
 	lock->lf_next = NULL;
 	TAILQ_INIT(&lock->lf_blkhd);
 	lock->lf_flags = flags;
@@ -218,7 +256,7 @@ lf_setlock(struct lockf *lock)
 {
 	struct lockf *block;
 	struct lockf **head = lock->lf_head;
-	struct lockf **prev, *overlap, *ltmp;
+	struct lockf *prev, *overlap, *ltmp;
 	static char lockstr[] = "lockf";
 	int ovcase, priority, needtolink, error;
 
@@ -285,6 +323,8 @@ lf_setlock(struct lockf *lock)
 		/*
 		 * Add our lock to the blocked list and sleep until we're free.
 		 * Remember who blocked us (for deadlock detection).
+		 * Since lock is not yet part of any list, it's safe to let the
+		 * lf_next field refer to the blocking lock.
 		 */
 		lock->lf_next = block;
 #ifdef LOCKF_DEBUG
@@ -312,8 +352,9 @@ lf_setlock(struct lockf *lock)
 	 * Skip over locks owned by other processes.
 	 * Handle any locks that overlap and are owned by ourselves.
 	 */
-	prev = head;
 	block = *head;
+	prev = NULL;
+	overlap = NULL;
 	needtolink = 1;
 	for (;;) {
 		ovcase = lf_findoverlap(block, lock, SELF, &prev, &overlap);
@@ -331,8 +372,12 @@ lf_setlock(struct lockf *lock)
 		switch (ovcase) {
 		case 0: /* no overlap */
 			if (needtolink) {
-				*prev = lock;
-				lock->lf_next = overlap;
+				if (overlap)	/* insert before overlap */
+					lf_link(lock, overlap);
+				else if (prev)	/* last lock in list */
+					lf_link(prev, lock);
+				else		/* first lock in list */
+					*head = lock;
 			}
 			break;
 		case 1: /* overlap == lock */
@@ -352,20 +397,14 @@ 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;
 			}
 			if (overlap->lf_start == lock->lf_start) {
-				*prev = lock;
-				lock->lf_next = overlap;
+				if (!needtolink)
+					lf_unlink(lock);
+				lf_link(lock, overlap);
 				overlap->lf_start = lock->lf_end + 1;
 			} else
 				lf_split(overlap, lock);
@@ -393,22 +432,19 @@ lf_setlock(struct lockf *lock)
 			 * Add the new lock if necessary and delete the overlap.
 			 */
 			if (needtolink) {
-				*prev = lock;
-				lock->lf_next = overlap->lf_next;
-				prev = &lock->lf_next;
+				lf_link(lock, overlap);
 				needtolink = 0;
-			} else
-				*prev = overlap->lf_next;
+			}
 			lf_free(overlap);
 			continue;
 		case 4: /* overlap starts before lock */
 			/*
 			 * Add lock after overlap on the list.
 			 */
-			lock->lf_next = overlap->lf_next;
-			overlap->lf_next = lock;
+			if (!needtolink)
+				lf_unlink(lock);
+			lf_link(overlap, lock);
 			overlap->lf_end = lock->lf_start - 1;
-			prev = &overlap->lf_next;
 			lf_wakelock(overlap);
 			needtolink = 0;
 			continue;
@@ -416,10 +452,8 @@ lf_setlock(struct lockf *lock)
 			/*
 			 * Add the new lock before overlap.
 			 */
-			if (needtolink) {
-				*prev = lock;
-				lock->lf_next = overlap;
-			}
+			if (needtolink)
+				lf_link(lock, overlap);
 			overlap->lf_start = lock->lf_end + 1;
 			lf_wakelock(overlap);
 			break;
@@ -445,7 +479,7 @@ lf_clearlock(struct lockf *lock)
 {
 	struct lockf **head = lock->lf_head;
 	struct lockf *lf = *head;
-	struct lockf *overlap, **prev;
+	struct lockf *overlap, *prev;
 	int ovcase;
 
 	if (lf == NULL)
@@ -454,13 +488,11 @@ lf_clearlock(struct lockf *lock)
 	if (lockf_debug & DEBUG_CLEARLOCK)
 		lf_print("lf_clearlock", lock);
 #endif /* LOCKF_DEBUG */
-	prev = head;
 	while ((ovcase = lf_findoverlap(lf, lock, SELF, &prev, &overlap))) {
 		lf_wakelock(overlap);
 
 		switch (ovcase) {
 		case 1: /* overlap == lock */
-			*prev = overlap->lf_next;
 			lf_free(overlap);
 			break;
 		case 2: /* overlap contains lock: split it */
@@ -469,16 +501,13 @@ lf_clearlock(struct lockf *lock)
 				break;
 			}
 			lf_split(overlap, lock);
-			overlap->lf_next = lock->lf_next;
 			break;
 		case 3: /* lock contains overlap */
-			*prev = overlap->lf_next;
 			lf = overlap->lf_next;
 			lf_free(overlap);			
 			continue;
 		case 4: /* overlap starts before lock */
 			overlap->lf_end = lock->lf_start - 1;
-			prev = &overlap->lf_next;
 			lf = overlap->lf_next;
 			continue;
 		case 5: /* overlap ends after lock */
@@ -526,10 +555,9 @@ lf_getlock(struct lockf *lock, struct fl
 struct lockf *
 lf_getblock(struct lockf *lock)
 {
-	struct lockf **prev, *overlap, *lf;
+	struct lockf *prev, *overlap, *lf;
 
-	prev = lock->lf_head;
-	lf = *prev;
+	lf = *lock->lf_head;
 	while (lf_findoverlap(lf, lock, OTHERS, &prev, &overlap) != 0) {
 		/*
 		 * We've found an overlap, see if it blocks us
@@ -554,7 +582,7 @@ lf_getblock(struct lockf *lock)
  */
 int
 lf_findoverlap(struct lockf *lf, struct lockf *lock, int type,
-    struct lockf ***prev, struct lockf **overlap)
+    struct lockf **prev, struct lockf **overlap)
 {
 	off_t start, end;
 
@@ -569,7 +597,7 @@ lf_findoverlap(struct lockf *lf, struct 
 	while (lf != NULL) {
 		if (((type & SELF) && lf->lf_id != lock->lf_id) ||
 		    ((type & OTHERS) && lf->lf_id == lock->lf_id)) {
-			*prev = &lf->lf_next;
+			*prev = lf;
 			*overlap = lf = lf->lf_next;
 			continue;
 		}
@@ -595,7 +623,7 @@ lf_findoverlap(struct lockf *lf, struct 
 			DPRINTF(("no overlap\n"), DEBUG_FINDOVR);
 			if ((type & SELF) && end != -1 && lf->lf_start > end)
 				return (0);
-			*prev = &lf->lf_next;
+			*prev = lf;
 			*overlap = lf = lf->lf_next;
 			continue;
 		}
@@ -649,18 +677,18 @@ lf_split(struct lockf *lock1, struct loc
 		lf_print("splitting from", lock2);
 	}
 #endif /* LOCKF_DEBUG */
+
 	/*
 	 * Check to see if splitting into only two pieces.
 	 */
 	if (lock1->lf_start == lock2->lf_start) {
 		lock1->lf_start = lock2->lf_end + 1;
-		lock2->lf_next = lock1;
+		lf_link(lock2, lock1);
 		return;
 	}
 	if (lock1->lf_end == lock2->lf_end) {
 		lock1->lf_end = lock2->lf_start - 1;
-		lock2->lf_next = lock1->lf_next;
-		lock1->lf_next = lock2;
+		lf_link(lock1, lock2);
 		return;
 	}
 	/*
@@ -669,13 +697,15 @@ lf_split(struct lockf *lock1, struct loc
 	 */
 	splitlock = lf_alloc(lock1->lf_uid, 0);
 	memcpy(splitlock, lock1, sizeof(*splitlock));
+	splitlock->lf_prev = NULL;
+	splitlock->lf_next = NULL;
 	splitlock->lf_start = lock2->lf_end + 1;
 	splitlock->lf_block.tqe_next = NULL;
 	TAILQ_INIT(&splitlock->lf_blkhd);
 	lock1->lf_end = lock2->lf_start - 1;
 
-	lock2->lf_next = splitlock;
-	lock1->lf_next = lock2;
+	lf_link(lock1, lock2);
+	lf_link(lock2, splitlock);
 }
 
 /*
Index: sys/sys/lockf.h
===================================================================
RCS file: /cvs/src/sys/sys/lockf.h,v
retrieving revision 1.9
diff -u -p -r1.9 lockf.h
--- sys/sys/lockf.h	24 Mar 2013 17:45:25 -0000	1.9
+++ sys/sys/lockf.h	12 Nov 2018 19:12:01 -0000
@@ -50,6 +50,7 @@ struct lockf {
 	off_t	lf_end;		 /* The byte # of the end of the lock (-1=EOF)*/
 	caddr_t	lf_id;		 /* The id of the resource holding the lock */
 	struct	lockf **lf_head; /* Back pointer to the head of lockf list */
+	struct	lockf *lf_prev;	 /* A pointer to the previous lock on this inode */
 	struct	lockf *lf_next;	 /* A pointer to the next lock on this inode */
 	struct	locklist lf_blkhd;	/* The list of blocked locks */
 	TAILQ_ENTRY(lockf) lf_block; /* A request waiting for a lock */
@@ -67,13 +68,15 @@ int	 lf_advlock(struct lockf **,
 	    off_t, caddr_t, int, struct flock *, int);
 int	 lf_clearlock(struct lockf *);
 int	 lf_findoverlap(struct lockf *,
-	    struct lockf *, int, struct lockf ***, struct lockf **);
+	    struct lockf *, int, struct lockf **, struct lockf **);
 struct lockf *
 	 lf_getblock(struct lockf *);
 int	 lf_getlock(struct lockf *, struct flock *);
 int	 lf_setlock(struct lockf *);
 void	 lf_split(struct lockf *, struct lockf *);
 void	 lf_wakelock(struct lockf *);
+void	 lf_link(struct lockf *, struct lockf *);
+void	 lf_unlink(struct lockf *);
 __END_DECLS
 
 #ifdef LOCKF_DEBUG