Module Name: src Committed By: bouyer Date: Sat Sep 5 11:36:29 UTC 2009
Modified Files: src/sys/kern [netbsd-5]: vfs_lockf.c Log Message: Pull up following revision(s) (requested by dsl in ticket #900): sys/kern/vfs_lockf.c: revision 1.72 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.69.4.2 -r1.69.4.3 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.69.4.2 src/sys/kern/vfs_lockf.c:1.69.4.3 --- src/sys/kern/vfs_lockf.c:1.69.4.2 Wed Jul 1 22:49:43 2009 +++ src/sys/kern/vfs_lockf.c Sat Sep 5 11:36:29 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_lockf.c,v 1.69.4.2 2009/07/01 22:49:43 snj Exp $ */ +/* $NetBSD: vfs_lockf.c,v 1.69.4.3 2009/09/05 11:36:29 bouyer Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_lockf.c,v 1.69.4.2 2009/07/01 22:49:43 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_lockf.c,v 1.69.4.3 2009/09/05 11:36:29 bouyer 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.