Module Name: src Committed By: dsl Date: Wed Aug 5 19:39:50 UTC 2009
Modified Files: src/sys/kern: vfs_lockf.c Log Message: lockf() passes its arguments through to fcntl() but is supposed to support -ve lengths (lock area before current offset). Nothing in libc or the kernel allowed for this, so some random part of the file would get locked (no idea which bits). Although this could probably be fixed in libc, the stubs for posix file locks for emulations could easily get into the kernel with -ve lengths. So fixing in the kernel avoids those problems. This also fixes PR/41620 (attempting to lock negative offsets) - which is what I was looking into! To generate a diff of this commit: cvs rdiff -u -r1.71 -r1.72 src/sys/kern/vfs_lockf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_lockf.c diff -u src/sys/kern/vfs_lockf.c:1.71 src/sys/kern/vfs_lockf.c:1.72 --- src/sys/kern/vfs_lockf.c:1.71 Wed Jun 10 22:34:35 2009 +++ src/sys/kern/vfs_lockf.c Wed Aug 5 19:39:50 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_lockf.c,v 1.71 2009/06/10 22:34:35 yamt Exp $ */ +/* $NetBSD: vfs_lockf.c,v 1.72 2009/08/05 19:39:50 dsl Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_lockf.c,v 1.71 2009/06/10 22:34:35 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_lockf.c,v 1.72 2009/08/05 19:39:50 dsl Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -835,6 +835,18 @@ default: return EINVAL; } + + if (fl->l_len == 0) + end = -1; + else { + if (fl->l_len > 0) + end = start + fl->l_len - 1; + else { + /* lockf() allows -ve lengths */ + end = start - 1; + start += fl->l_len; + } + } if (start < 0) return EINVAL; @@ -869,11 +881,6 @@ return EINVAL; } - if (fl->l_len == 0) - end = -1; - else - end = start + fl->l_len - 1; - switch (ap->a_op) { case F_SETLK: lock = lf_alloc(1); @@ -922,7 +929,7 @@ if (lock->lf_flags & F_POSIX) { KASSERT(curproc == (struct proc *)ap->a_id); } - lock->lf_id = (struct proc *)ap->a_id; + lock->lf_id = ap->a_id; /* * Do the requested operation.