/*
 * Check permission.  The two basic access models of FUSE are:
 *
 * 1) Local access checking ('default_permissions' mount option) based
 * on file mode.  This is the plain old disk filesystem permission
 * modell.
 *
 * 2) "Remote" access checking, where server is responsible for
 * checking permission in each inode operation.  An exception to this
 * is if ->permission() was invoked from sys_access() in which case an
 * access request is sent.  Execute permission is still checked
 * locally based on file mode.
 */
static int fuse_permission(struct inode *inode, int mask)
{
	struct fuse_conn *fc = get_fuse_conn(inode);
	bool refreshed = false;
	int err = 0;

	if (!fuse_allow_task(fc, current))
		return -EACCES;

	/*
	 * If attributes are needed, refresh them before proceeding
	 */
	if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
		struct fuse_inode *fi = get_fuse_inode(inode);

		if (fi->i_time < get_jiffies_64()) {
			refreshed = true;

			err = fuse_perm_getattr(inode, mask);
			if (err)
				return err;
		}
	}

	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
		err = generic_permission(inode, mask);

		/* If permission is denied, try to refresh file
		   attributes.  This is also needed, because the root
		   node will at first have no permissions */
		if (err == -EACCES && !refreshed) {
			err = fuse_perm_getattr(inode, mask);
			if (!err)
				err = generic_permission(inode, mask);
		}

		/* Note: the opposite of the above test does not
		   exist.  So if permissions are revoked this won't be
		   noticed immediately, only after the attribute
		   timeout has expired */
	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
		if (mask & MAY_NOT_BLOCK)
			return -ECHILD;

		err = fuse_access(inode, mask);
	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
		if (!(inode->i_mode & S_IXUGO)) {
			if (refreshed)
				return -EACCES;

			err = fuse_perm_getattr(inode, mask);
			if (!err && !(inode->i_mode & S_IXUGO))
				return -EACCES;
		}
	}
	return err;
}
static int fuse_permission(struct inode *inode, int mask)
{
	struct fuse_conn *fc = get_fuse_conn(inode);
	bool refreshed = false;
	int err = 0;

	if (!fuse_allow_task(fc, current))
		return -EACCES;

	/*
                                                            
  */
	if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
		struct fuse_inode *fi = get_fuse_inode(inode);

		if (fi->i_time < get_jiffies_64()) {
			refreshed = true;

			err = fuse_perm_getattr(inode, mask);
			if (err)
				return err;
		}
	}

	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
		err = generic_permission(inode, mask);

		/*                                             
                                                       
                                            */
		if (err == -EACCES && !refreshed) {
			err = fuse_perm_getattr(inode, mask);
			if (!err)
				err = generic_permission(inode, mask);
		}

		/*                                              
                                                        
                                                  
                         */
	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
		if (mask & MAY_NOT_BLOCK)
			return -ECHILD;

		err = fuse_access(inode, mask);
	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
		if (!(inode->i_mode & S_IXUGO)) {
			if (refreshed)
				return -EACCES;

			err = fuse_perm_getattr(inode, mask);
			if (!err && !(inode->i_mode & S_IXUGO))
				return -EACCES;
		}
	}
	return err;
}
Exemple #3
0
/*
 * Check permission.  The two basic access models of FUSE are:
 *
 * 1) Local access checking ('default_permissions' mount option) based
 * on file mode.  This is the plain old disk filesystem permission
 * modell.
 *
 * 2) "Remote" access checking, where server is responsible for
 * checking permission in each inode operation.  An exception to this
 * is if ->permission() was invoked from sys_access() in which case an
 * access request is sent.  Execute permission is still checked
 * locally based on file mode.
 */
static int fuse_permission(struct inode *inode, int mask)
{
	struct fuse_conn *fc = get_fuse_conn(inode);
	bool refreshed = false;
	int err = 0;

	if (!fuse_allow_current_process(fc))
		return -EACCES;

	/*
	 * If attributes are needed, refresh them before proceeding
	 */
	if (fc->default_permissions ||
	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
		struct fuse_inode *fi = get_fuse_inode(inode);
		u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID;

		if (perm_mask & READ_ONCE(fi->inval_mask) ||
		    time_before64(fi->i_time, get_jiffies_64())) {
			refreshed = true;

			err = fuse_perm_getattr(inode, mask);
			if (err)
				return err;
		}
	}

	if (fc->default_permissions) {
		err = generic_permission(inode, mask);

		/* If permission is denied, try to refresh file
		   attributes.  This is also needed, because the root
		   node will at first have no permissions */
		if (err == -EACCES && !refreshed) {
			err = fuse_perm_getattr(inode, mask);
			if (!err)
				err = generic_permission(inode, mask);
		}

		/* Note: the opposite of the above test does not
		   exist.  So if permissions are revoked this won't be
		   noticed immediately, only after the attribute
		   timeout has expired */
	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
		err = fuse_access(inode, mask);
	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
		if (!(inode->i_mode & S_IXUGO)) {
			if (refreshed)
				return -EACCES;

			err = fuse_perm_getattr(inode, mask);
			if (!err && !(inode->i_mode & S_IXUGO))
				return -EACCES;
		}
	}
	return err;
}
Exemple #4
0
int handle_permission(struct inode *inode, int mask)
{
	int submask;
	umode_t mode = inode->i_mode;

	if (mask & MAY_WRITE) {

		/*
		 * Nobody gets write access to a read-only fs.
		 */
		if (IS_RDONLY(inode) &&
		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
			return -EROFS;

		/*
		 * Nobody gets write access to an immutable file.
		 */
		if (IS_IMMUTABLE(inode))
			return -EACCES;
	}

	/*
	 * MAY_EXEC on regular files requires special handling: We override
	 * filesystem execute permissions if the mode bits aren't set.
	 */
	if ((mask & MAY_EXEC) && S_ISREG(mode) && !(mode & S_IXUGO))
		return -EACCES;

	/* Ordinary permission routines do not understand MAY_APPEND. */
	submask = mask & ~MAY_APPEND;
#ifdef IN_KERNEL_CHANGE_NOT_SUPP

	/* FIXME! we don't have nameidata for handle lookup. So not sure how
         * we can check for inode->permissions. We already limit the call
         * to CAP_DAC_OVERRIDE. So we should be able to skip the ACL check.
         * But we also skip security_inode_permission below.
         */

	if (inode->i_op && inode->i_op->permission)
		retval = inode->i_op->permission(inode, submask, nd);
	else
		retval = generic_permission(inode, submask, NULL);
	if (retval)
		return retval;

	return security_inode_permission(inode, mask, nd);
#else
        return generic_permission(inode, submask, NULL);
#endif

}
Exemple #5
0
/*
 * Check permission.  The two basic access models of FUSE are:
 *
 * 1) Local access checking ('default_permissions' mount option) based
 * on file mode.  This is the plain old disk filesystem permission
 * modell.
 *
 * 2) "Remote" access checking, where server is responsible for
 * checking permission in each inode operation.  An exception to this
 * is if ->permission() was invoked from sys_access() in which case an
 * access request is sent.  Execute permission is still checked
 * locally based on file mode.
 */
static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
{
	struct fuse_conn *fc = get_fuse_conn(inode);

	if (!fuse_allow_task(fc, current))
		return -EACCES;
	else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
#ifdef KERNEL_2_6_10_PLUS
		int err = generic_permission(inode, mask, NULL);
#else
		int err = vfs_permission(inode, mask);
#endif

		/* If permission is denied, try to refresh file
		   attributes.  This is also needed, because the root
		   node will at first have no permissions */
		if (err == -EACCES) {
		 	err = fuse_do_getattr(inode);
			if (!err)
#ifdef KERNEL_2_6_10_PLUS
				err = generic_permission(inode, mask, NULL);
#else
				err = vfs_permission(inode, mask);
#endif
		}

		/* Note: the opposite of the above test does not
		   exist.  So if permissions are revoked this won't be
		   noticed immediately, only after the attribute
		   timeout has expired */

		return err;
	} else {
		int mode = inode->i_mode;
#ifndef KERNEL_2_6_11_PLUS
		if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
                    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
                        return -EROFS;
#endif
		if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
			return -EACCES;

#ifndef LOOKUP_CHDIR
#define LOOKUP_CHDIR 0
#endif
		if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
			return fuse_access(inode, mask);
		return 0;
	}
}
Exemple #6
0
/* Basically copied from the kernel vfs permission(), but we've changed
 * the following: (1) the IS_RDONLY check is skipped, and (2) if you set
 * the mount option `nfsperms=insceure', we assume that -EACCES means that
 * the export is read-only and we should check standard Unix permissions.
 * This means that NFS ACL checks (or other advanced permission features)
 * are bypassed.
 */
static int inode_permission(struct inode *inode, int mask, struct nameidata *nd,
			    int bindex)
{
	int retval, submask;

	if (mask & MAY_WRITE) {
		/* The first branch is allowed to be really readonly. */
		if (bindex == 0) {
			umode_t mode = inode->i_mode;
			if (IS_RDONLY(inode) && (S_ISREG(mode) || S_ISDIR(mode)
						 || S_ISLNK(mode)))
				return -EROFS;
		}
		/*
		 * Nobody gets write access to an immutable file.
		 */
		if (IS_IMMUTABLE(inode))
			return -EACCES;
	}

	/* Ordinary permission routines do not understand MAY_APPEND. */
	submask = mask & ~MAY_APPEND;
	if (inode->i_op && inode->i_op->permission) {
		retval = inode->i_op->permission(inode, submask, nd);
		if ((retval == -EACCES) && (submask & MAY_WRITE) &&
		    (!strcmp("nfs", (inode)->i_sb->s_type->name)) &&
		    (nd) && (nd->mnt) && (nd->mnt->mnt_sb) &&
		    (branchperms(nd->mnt->mnt_sb, bindex) & MAY_NFSRO)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
			retval = vfs_permission(inode, submask);
#else
			retval = generic_permission(inode, submask, NULL);
#endif
		}
	} else {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
		retval = vfs_permission(inode, submask);
#else
		retval = generic_permission(inode, submask, NULL);
#endif
	}
	
	if (retval && retval != -EROFS) /* ignore EROFS */
		return retval;

	retval = security_inode_permission(inode, mask, nd);
	return ((retval == -EROFS) ? 0 : retval); /* ignore EROFS */
}
STATIC int
xfs_vn_permission(
	struct inode		*inode,
	int			mask)
{
	return generic_permission(inode, mask, xfs_check_acl);
}
Exemple #8
0
int ovl_permission(struct inode *inode, int mask)
{
	struct inode *upperinode = ovl_inode_upper(inode);
	struct inode *realinode = upperinode ?: ovl_inode_lower(inode);
	const struct cred *old_cred;
	int err;

	/* Careful in RCU walk mode */
	if (!realinode) {
		WARN_ON(!(mask & MAY_NOT_BLOCK));
		return -ECHILD;
	}

	/*
	 * Check overlay inode with the creds of task and underlying inode
	 * with creds of mounter
	 */
	err = generic_permission(inode, mask);
	if (err)
		return err;

	old_cred = ovl_override_creds(inode->i_sb);
	if (!upperinode &&
	    !special_file(realinode->i_mode) && mask & MAY_WRITE) {
		mask &= ~(MAY_WRITE | MAY_APPEND);
		/* Make sure mounter can read file for copy up later */
		mask |= MAY_READ;
	}
	err = inode_permission(realinode, mask);
	revert_creds(old_cred);

	return err;
}
Exemple #9
0
static int esdfs_permission(struct inode *inode, int mask)
{
	struct esdfs_sb_info *sbi = ESDFS_SB(inode->i_sb);
	struct inode *lower_inode;
	int err;

	/* First, check the upper permissions */
	err = generic_permission(inode, mask);

	/* Basic checking of the lower inode (can't override creds here) */
	lower_inode = esdfs_lower_inode(inode);
	if (lower_inode->i_uid != sbi->lower_perms.uid ||
	    lower_inode->i_gid != sbi->lower_perms.gid ||
	    S_ISSOCK(lower_inode->i_mode) ||
	    S_ISLNK(lower_inode->i_mode) ||
	    S_ISBLK(lower_inode->i_mode) ||
	    S_ISCHR(lower_inode->i_mode) ||
	    S_ISFIFO(lower_inode->i_mode))
		err = -EACCES;

	/* Finally, check the derived permissions */
	if (!err && ESDFS_DERIVE_PERMS(ESDFS_SB(inode->i_sb)))
		err = esdfs_check_derived_permission(inode, mask);

	return err;
}
Exemple #10
0
/*
 * This is a variant of fs/namei.c:permission() or inode_permission() which
 * skips over EROFS tests (because we perform copyup on EROFS).
 */
static int __inode_permission(struct inode *inode, int mask)
{
	int retval;

	/* nobody gets write access to an immutable file */
	if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
		return -EACCES;

	/* Ordinary permission routines do not understand MAY_APPEND. */
	if (inode->i_op && inode->i_op->permission) {
		retval = inode->i_op->permission(inode, mask);
		if (!retval) {
			/*
			 * Exec permission on a regular file is denied if none
			 * of the execute bits are set.
			 *
			 * This check should be done by the ->permission()
			 * method.
			 */
			if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode) &&
			    !(inode->i_mode & S_IXUGO))
				return -EACCES;
		}
	} else {
		retval = generic_permission(inode, mask);
	}
	if (retval)
		return retval;

	return security_inode_permission(inode,
			mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
}
Exemple #11
0
static int h_permission(struct inode *h_inode, int mask,
			struct vfsmount *h_mnt, int brperm)
{
	int err;
	const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));

	err = -EACCES;
	if ((write_mask && IS_IMMUTABLE(h_inode))
	    || ((mask & MAY_EXEC)
		&& S_ISREG(h_inode->i_mode)
		&& ((h_mnt->mnt_flags & MNT_NOEXEC)
		    || !(h_inode->i_mode & S_IXUGO))))
		goto out;

	/*
	 * - skip the lower fs test in the case of write to ro branch.
	 * - nfs dir permission write check is optimized, but a policy for
	 *   link/rename requires a real check.
	 * - nfs always sets MS_POSIXACL regardless its mount option 'noacl.'
	 *   in this case, generic_permission() returns -EOPNOTSUPP.
	 */
	if ((write_mask && !au_br_writable(brperm))
	    || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
		&& write_mask && !(mask & MAY_READ))
	    || !h_inode->i_op->permission) {
		/* AuLabel(generic_permission); */
		/* AuDbg("get_acl %pf\n", h_inode->i_op->get_acl); */
		err = generic_permission(h_inode, mask);
		if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode))
			err = h_inode->i_op->permission(h_inode, mask);
		AuTraceErr(err);
	} else {
		/* AuLabel(h_inode->permission); */
		err = h_inode->i_op->permission(h_inode, mask);
		AuTraceErr(err);
	}

	if (!err)
		err = devcgroup_inode_permission(h_inode, mask);
	if (!err)
		err = security_inode_permission(h_inode, mask);

#if 0
	if (!err) {
		/* todo: do we need to call ima_path_check()? */
		struct path h_path = {
			.dentry	=
			.mnt	= h_mnt
		};
		err = ima_path_check(&h_path,
				     mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
				     IMA_COUNT_LEAVE);
	}
#endif

out:
	return err;
}
Exemple #12
0
/*
 * /proc/pid/fd needs a special permission handler so that a process can still
 * access /proc/self/fd after it has executed a setuid().
 */
int proc_fd_permission(struct inode *inode, int mask)
{
	int rv = generic_permission(inode, mask);
	if (rv == 0)
		return 0;
	if (task_tgid(current) == proc_pid(inode))
		rv = 0;
	return rv;
}
Exemple #13
0
int reiserfs_permission(struct inode *inode, int mask)
{
	/*
	 * We don't do permission checks on the internal objects.
	 * Permissions are determined by the "owning" object.
	 */
	if (IS_PRIVATE(inode))
		return 0;

#ifdef CONFIG_REISERFS_FS_XATTR
	/*
	 * Stat data v1 doesn't support ACLs.
	 */
	if (get_inode_sd_version(inode) != STAT_DATA_V1)
		return generic_permission(inode, mask, reiserfs_check_acl);
#endif
	return generic_permission(inode, mask, NULL);
}
Exemple #14
0
int nilfs_permission(struct inode *inode, int mask)
{
	struct nilfs_root *root = NILFS_I(inode)->i_root;
	if ((mask & MAY_WRITE) && root &&
	    root->cno != NILFS_CPTREE_CURRENT_CNO)
		return -EROFS; /* snapshot is not writable */

	return generic_permission(inode, mask);
}
Exemple #15
0
extern int
vnode_shadow_iop_permission(
    INODE_T *inode,
    int mask
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
    , struct nameidata *nd
#endif
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
    , unsigned int flags
#endif
)
{
    INODE_T *real_inode;
    DENT_T *dp;
    int err;

    /* we don't have multiple dentries per shadow inode, so this is OK */
    dp = vnlayer_inode2dentry_internal(inode, NULL, NULL, NULL);
    ASSERT(dp != NULL);
    real_inode = REALDENTRY(dp)->d_inode;

    if (real_inode == NULL) {        /* just in case; not expected! */
        VNODE_DPUT(dp);
        return -EACCES;
    }
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
    err = permission(real_inode, mask, nd);
#else
    err = inode_permission(real_inode, mask);
#endif

    if (err == 0) {
        /* don't call permission() on inode, it will call back to us! */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
        err = vfs_permission(inode, mask);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
        err = generic_permission(inode, mask, NULL);
#else
        err = generic_permission(inode, mask, flags, NULL);
#endif
    }
    VNODE_DPUT(dp);
    return(err);
}
Exemple #16
0
int sysfs_permission(struct inode *inode, int mask)
{
	struct sysfs_dirent *sd = inode->i_private;

	mutex_lock(&sysfs_mutex);
	sysfs_refresh_inode(sd, inode);
	mutex_unlock(&sysfs_mutex);

	return generic_permission(inode, mask, NULL);
}
Exemple #17
0
int reiserfs_permission(struct inode *inode, int mask)
{
	/*
	 * We don't do permission checks on the internal objects.
	 * Permissions are determined by the "owning" object.
	 */
	if (IS_PRIVATE(inode))
		return 0;

	return generic_permission(inode, mask);
}
Exemple #18
0
static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
{
	struct cifs_sb_info *cifs_sb;

	cifs_sb = CIFS_SB(inode->i_sb);

	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
		return 0;
	} else /* file mode might have been restricted at mount time 
		on the client (above and beyond ACL on servers) for  
		servers which do not support setting and viewing mode bits,
		so allowing client to check permissions is useful */ 
		return generic_permission(inode, mask, NULL);
}
Exemple #19
0
int sysfs_permission(struct inode *inode, int mask, unsigned int flags)
{
	struct sysfs_dirent *sd;

	if (flags & IPERM_FLAG_RCU)
		return -ECHILD;

	sd = inode->i_private;

	mutex_lock(&sysfs_mutex);
	sysfs_refresh_inode(sd, inode);
	mutex_unlock(&sysfs_mutex);

	return generic_permission(inode, mask, flags, NULL);
}
Exemple #20
0
int sysfs_permission(struct inode *inode, int mask)
{
	struct sysfs_dirent *sd;

	if (mask & MAY_NOT_BLOCK)
		return -ECHILD;

	sd = inode->i_private;

	mutex_lock(&sysfs_mutex);
	sysfs_refresh_inode(sd, inode);
	mutex_unlock(&sysfs_mutex);

	return generic_permission(inode, mask);
}
Exemple #21
0
int kernfs_iop_permission(struct inode *inode, int mask)
{
	struct kernfs_node *kn;

	if (mask & MAY_NOT_BLOCK)
		return -ECHILD;

	kn = inode->i_private;

	mutex_lock(&kernfs_mutex);
	kernfs_refresh_inode(kn, inode);
	mutex_unlock(&kernfs_mutex);

	return generic_permission(inode, mask);
}
Exemple #22
0
int orangefs_permission(struct inode *inode, int mask)
{
	int ret;

	if (mask & MAY_NOT_BLOCK)
		return -ECHILD;

	gossip_debug(GOSSIP_INODE_DEBUG, "%s: refreshing\n", __func__);

	/* Make sure the permission (and other common attrs) are up to date. */
	ret = orangefs_inode_getattr(inode, 0, 0);
	if (ret < 0)
		return ret;

	return generic_permission(inode, mask);
}
/*
 * /proc/pid/fd needs a special permission handler so that a process can still
 * access /proc/self/fd after it has executed a setuid().
 */
int proc_fd_permission(struct inode *inode, int mask)
{
	struct task_struct *p;
	int rv;

	rv = generic_permission(inode, mask);
	if (rv == 0)
		return rv;

	rcu_read_lock();
	p = pid_task(proc_pid(inode), PIDTYPE_PID);
	if (p && same_thread_group(p, current))
		rv = 0;
	rcu_read_unlock();

	return rv;
}
Exemple #24
0
static int cifs_permission(struct inode *inode, int mask, unsigned int flags)
{
	struct cifs_sb_info *cifs_sb;

	cifs_sb = CIFS_SB(inode->i_sb);

	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
		if ((mask & MAY_EXEC) && !execute_ok(inode))
			return -EACCES;
		else
			return 0;
	} else /* file mode might have been restricted at mount time
		on the client (above and beyond ACL on servers) for
		servers which do not support setting and viewing mode bits,
		so allowing client to check permissions is useful */
		return generic_permission(inode, mask, flags, NULL);
}
Exemple #25
0
int
gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
	       const struct dentry *dir, const int flag, const int acc_mode)
{
#ifdef CONFIG_GRKERNSEC_FIFO
	const struct cred *cred = current_cred();

	if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
	    !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
	    (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
	    (cred->fsuid != dentry->d_inode->i_uid)) {
		if (!generic_permission(dentry->d_inode, acc_mode, NULL))
			gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
		return -EACCES;
	}
#endif
	return 0;
}
Exemple #26
0
/*
 * /proc/pid/fd needs a special permission handler so that a process can still
 * access /proc/self/fd after it has executed a setuid().
 */
int proc_fd_permission(struct inode *inode, int mask)
{
	struct task_struct *task;
	int rv = generic_permission(inode, mask);

	if (task_tgid(current) == proc_pid(inode))
		rv = 0;

	task = get_proc_task(inode);
	if (task == NULL)
		return rv;

	if (gr_acl_handle_procpidmem(task))
		rv = -EACCES;

	put_task_struct(task);

	return rv;
}
Exemple #27
0
int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
{
	int ret;

	mlog_entry_void();

	ret = ocfs2_meta_lock(inode, NULL, 0);
	if (ret) {
		if (ret != -ENOENT)
			mlog_errno(ret);
		goto out;
	}

	ret = generic_permission(inode, mask, NULL);

	ocfs2_meta_unlock(inode, 0);
out:
	mlog_exit(ret);
	return ret;
}
Exemple #28
0
static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
{
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_holder i_gh;
	int error;
	int unlock = 0;

	if (gfs2_glock_is_locked_by_me(ip->i_gl) == 0) {
		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
		if (error)
			return error;
		unlock = 1;
	}

	error = generic_permission(inode, mask, gfs2_check_acl);
	if (unlock)
		gfs2_glock_dq_uninit(&i_gh);

	return error;
}
static int sdcardfs_permission(struct inode *inode, int mask, unsigned int flags)
{
	int err;

	if (flags & IPERM_FLAG_RCU)
		return -ECHILD;
	
	/*
	 * Permission check on sdcardfs inode.
	 * Calling process should have AID_SDCARD_RW permission 
	 */
	err = generic_permission(inode, mask, 0, inode->i_op->check_acl);

	/* XXX 
	 * Original sdcardfs code calls inode_permission(lower_inode,.. )
	 * for checking inode permission. But doing such things here seems
	 * duplicated work, because the functions called after this func, 
	 * such as vfs_create, vfs_unlink, vfs_rename, and etc, 
	 * does exactly same thing, i.e., they calls inode_permission(). 
	 * So we just let they do the things. 
	 * If there are any security hole, just uncomment following if block. 
	 */
#if 0
	if (!err) {
		/* 
		 * Permission check on lower_inode(=EXT4). 
		 * we check it with AID_MEDIA_RW permission 
		 */
		struct inode *lower_inode;
		OVERRIDE_CRED(SDCARDFS_SB(inode->sb));

		lower_inode = sdcardfs_lower_inode(inode);
		err = inode_permission(lower_inode, mask);

		REVERT_CRED();
	}
#endif
	return err; 

}
Exemple #30
0
int gfs2_permission(struct inode *inode, int mask)
{
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_holder i_gh;
	int error;
	int unlock = 0;

	if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) {
		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
		if (error)
			return error;
		unlock = 1;
	}

	if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
		error = -EACCES;
	else
		error = generic_permission(inode, mask, gfs2_check_acl);
	if (unlock)
		gfs2_glock_dq_uninit(&i_gh);

	return error;
}