Exemplo n.º 1
0
int locks_verify_locked(struct inode *inode)
{
	/* Candidates for mandatory locking have the setgid bit set
	 * but no group execute bit -  an otherwise meaningless combination.
	 */
	if (IS_MANDLOCK(inode) &&
	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
		return (locks_mandatory_locked(inode));
	return (0);
}
Exemplo n.º 2
0
int locks_verify_area(int read_write, struct inode *inode, struct file *filp,
		      unsigned int offset, unsigned int count)
{
	/* Candidates for mandatory locking have the setgid bit set
	 * but no group execute bit -  an otherwise meaningless combination.
	 */
	if (IS_MANDLOCK(inode) &&
	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
		return (locks_mandatory_area(read_write, inode, filp, offset,
					     count));
	return (0);
}
Exemplo n.º 3
0
/* Apply the lock described by l to an open file descriptor.
 * This implements both the F_SETLK and F_SETLKW commands of fcntl().
 * It also emulates flock() in a pretty broken way for older C
 * libraries.
 */
int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
{
	int error;
	struct file *filp;
	struct file_lock file_lock;
	struct flock flock;
	struct inode *inode;

	/* Get arguments and validate them ...
	 */

	if ((fd >= NR_OPEN) || !(filp = current->files->fd[fd]))
		return (-EBADF);
	
	error = verify_area(VERIFY_READ, l, sizeof(*l));
	if (error)
		return (error);
	
	if (!(inode = filp->f_inode))
		return (-EINVAL);
	
	/*
	 * This might block, so we do it before checking the inode.
	 */
	memcpy_fromfs(&flock, l, sizeof(flock));

	/* Don't allow mandatory locks on files that may be memory mapped
	 * and shared.
	 */
	if (IS_MANDLOCK(inode) &&
	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
	    inode->i_mmap) {
		struct vm_area_struct *vma = inode->i_mmap;
		do {
			if (vma->vm_flags & VM_MAYSHARE)
				return (-EAGAIN);
			vma = vma->vm_next_share;
		} while (vma != inode->i_mmap);
	}

	if (!posix_make_lock(filp, &file_lock, &flock))
		return (-EINVAL);
	
	switch (flock.l_type) {
	case F_RDLCK:
		if (!(filp->f_mode & 1))
			return (-EBADF);
		break;
	case F_WRLCK:
		if (!(filp->f_mode & 2))
			return (-EBADF);
		break;
	case F_UNLCK:
		break;
	case F_SHLCK:
	case F_EXLCK:
#if 1
/* warn a bit for now, but don't overdo it */
{
	static int count = 0;
	if (!count) {
		count=1;
		printk(KERN_WARNING
		       "fcntl_setlk() called by process %d (%s) with broken flock() emulation\n",
		       current->pid, current->comm);
	}
}
#endif
		if (!(filp->f_mode & 3))
			return (-EBADF);
		break;
	default:
		return (-EINVAL);
	}
	
	return (posix_lock_file(filp, &file_lock, cmd == F_SETLKW));
}
Exemplo n.º 4
0
/* Apply the lock described by l to an open file descriptor.
 * This implements both the F_SETLK and F_SETLKW commands of fcntl().
 */
int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
{
	struct file *filp;
	struct file_lock file_lock;
	struct flock flock;
	struct dentry * dentry;
	struct inode *inode;
	int error;

	/*
	 * This might block, so we do it before checking the inode.
	 */
	error = -EFAULT;
	if (copy_from_user(&flock, l, sizeof(flock)))
		goto out;

	/* Get arguments and validate them ...
	 */

	error = -EBADF;
	filp = fget(fd);
	if (!filp)
		goto out;

	error = -EINVAL;
	if (!(dentry = filp->f_dentry))
		goto out_putf;
	if (!(inode = dentry->d_inode))
		goto out_putf;

	/* Don't allow mandatory locks on files that may be memory mapped
	 * and shared.
	 */
	if (IS_MANDLOCK(inode) &&
	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
	    inode->i_mmap) {
		struct vm_area_struct *vma = inode->i_mmap;
		error = -EAGAIN;
		do {
			if (vma->vm_flags & VM_MAYSHARE)
				goto out_putf;
		} while ((vma = vma->vm_next_share) != NULL);
	}

	error = -EINVAL;
	if (!posix_make_lock(filp, &file_lock, &flock))
		goto out_putf;
	
	error = -EBADF;
	switch (flock.l_type) {
	case F_RDLCK:
		if (!(filp->f_mode & FMODE_READ))
			goto out_putf;
		break;
	case F_WRLCK:
		if (!(filp->f_mode & FMODE_WRITE))
			goto out_putf;
		break;
	case F_UNLCK:
		break;
	case F_SHLCK:
	case F_EXLCK:
#ifdef __sparc__
/* warn a bit for now, but don't overdo it */
{
	static int count = 0;
	if (!count) {
		count=1;
		printk(KERN_WARNING
		       "fcntl_setlk() called by process %d (%s) with broken flock() emulation\n",
		       current->pid, current->comm);
	}
}
		if (!(filp->f_mode & 3))
			goto out_putf;
		break;
#endif
	default:
		error = -EINVAL;
		goto out_putf;
	}

	if (filp->f_op->lock != NULL) {
		error = filp->f_op->lock(filp, cmd, &file_lock);
		if (error < 0)
			goto out_putf;
	}
	error = posix_lock_file(filp, &file_lock, cmd == F_SETLKW);

out_putf:
	fput(filp);
out:
	return error;
}