untrusted comment: verify with openbsd-63-base.pub
RWRxzbLwAd76ZXrF5y82i+3P6GPPKyKMr+4Gavd+jzA1P2AVu3tia4KkcWQ+8LnMi+4e8bb+9es0Ic2u+Itgs/wwOMVuFlBztA0=

OpenBSD 6.3 errata 023, 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-63-base.pub -x 023_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.25
diff -u -p -r1.25 vfs_lockf.c
--- sys/kern/vfs_lockf.c        26 Feb 2018 13:43:51 -0000      1.25
+++ sys/kern/vfs_lockf.c        12 Nov 2018 19:19:15 -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 */
@@ -357,8 +402,9 @@ lf_setlock(struct lockf *lock)
                               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);
@@ -386,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 = &lock->lf_next;
                       lf_wakelock(overlap);
                       needtolink = 0;
                       continue;
@@ -409,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;
@@ -438,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)
@@ -447,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 */
@@ -462,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 */
@@ -519,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
@@ -547,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;

@@ -562,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;
               }
@@ -588,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;
               }
@@ -642,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;
       }
       /*
@@ -662,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:19:15 -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