Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Jul 1998 17:34:24 -0700 (PDT)
From:      Tom <tom@uniserve.com>
To:        Brian Feldman <green@zone.baldcom.net>
Cc:        freebsd-current@FreeBSD.ORG
Subject:   Re: flock(2) problem & fix
Message-ID:  <Pine.BSF.3.96.980731173220.29794C-200000@shell.uniserve.ca>
In-Reply-To: <Pine.BSF.4.02.9807311954190.25645-200000@zone.baldcom.net>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]

On Fri, 31 Jul 1998, Brian Feldman wrote:

> 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

  I disagree.  The flock() method is advisory anyway.  In fact, the file
may exist for the sole purpose of flock'ing it.  I know several programs
that use lock files (which are always zero length) for locking purposes.

  Also, silently converting a exclusive lock request to a non-exclusive
lock is VERY bad.  Many programs will break.

Tom

[-- 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.3.96.980731173220.29794C-200000>