Date: Fri, 31 Jul 1998 20:05:19 -0400 (EDT) From: Brian Feldman <green@zone.baldcom.net> To: freebsd-current@FreeBSD.ORG Subject: flock(2) problem & fix Message-ID: <Pine.BSF.4.02.9807311954190.25645-200000@zone.baldcom.net>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Our flock(2) doesn't seem to do the right thing all the time. It seems
that any user with read access to a file is allowed exclusive locking of
it, which I think is wrong (does everyone agree?), and that a shared lock
should be used, because the user does not own the file, and has no write
permission, therefore no need for an exclusive lock. I raise the question
as to whether it should matter if the lock is non-blocking or not, and
that should be considered I suppose, as to assure the Right Thing will
happen. Attached is a patch to sys/kern/kern_descrip.c which should fix
the problem but is untested.
Cheers,
Brian Feldman
green@unixhelp.org
--- kern_descrip.c.old Fri Jul 31 18:28:30 1998
+++ kern_descrip.c Fri Jul 31 19:31:26 1998
@@ -986,6 +986,9 @@
register struct file *fp;
struct vnode *vp;
struct flock lf;
+ struct stat fst;
+ short gr;
+ boolean_t ok = 0;
if ((unsigned)uap->fd >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[uap->fd]) == NULL)
@@ -1007,10 +1010,27 @@
lf.l_type = F_RDLCK;
else
return (EBADF);
+ vn_stat((struct vnode *)fp->f_data, &fst, p);
+ if (uap->how & LOCK_EX && p->p_cred->pc_ucred->cr_uid != 0 &&
+ fp->f_cred->cr_uid != p->p_cred->pc_ucred->cr_uid &&
+ !(fst.st_mode & S_IWOTH) && !(fst.st_mode & S_IWGRP))
+ return (EPERM);
+ if (!(fst.st_mode & S_IWGRP))
+ ok = 1;
+ else {
+ for (gr = 0; gr < p->p_cred->pc_ucred->cr_ngroups; gr++)
+ if (p->p_cred->pc_ucred->cr_groups[gr - 1] == fst.st_gid)
{
+ ok = 1;
+ break;
+ }
+ }
+ if (ok) {
fp->f_flag |= FHASLOCK;
if (uap->how & LOCK_NB)
return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
F_FLOCK));
return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
F_FLOCK|F_WAIT));
+ } else
+ return (EPERM);
}
/*
[-- Attachment #2 --]
--- kern_descrip.c.old Fri Jul 31 18:28:30 1998
+++ kern_descrip.c Fri Jul 31 19:31:26 1998
@@ -986,6 +986,9 @@
register struct file *fp;
struct vnode *vp;
struct flock lf;
+ struct stat fst;
+ short gr;
+ boolean_t ok = 0;
if ((unsigned)uap->fd >= fdp->fd_nfiles ||
(fp = fdp->fd_ofiles[uap->fd]) == NULL)
@@ -1007,10 +1010,27 @@
lf.l_type = F_RDLCK;
else
return (EBADF);
+ vn_stat((struct vnode *)fp->f_data, &fst, p);
+ if (uap->how & LOCK_EX && p->p_cred->pc_ucred->cr_uid != 0 &&
+ fp->f_cred->cr_uid != p->p_cred->pc_ucred->cr_uid &&
+ !(fst.st_mode & S_IWOTH) && !(fst.st_mode & S_IWGRP))
+ return (EPERM);
+ if (!(fst.st_mode & S_IWGRP))
+ ok = 1;
+ else {
+ for (gr = 0; gr < p->p_cred->pc_ucred->cr_ngroups; gr++)
+ if (p->p_cred->pc_ucred->cr_groups[gr - 1] == fst.st_gid) {
+ ok = 1;
+ break;
+ }
+ }
+ if (ok) {
fp->f_flag |= FHASLOCK;
if (uap->how & LOCK_NB)
return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK));
return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT));
+ } else
+ return (EPERM);
}
/*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.02.9807311954190.25645-200000>
