/* Call both cr_permision() and cr_dentry_open(). */ struct file * cr_dentry_open_perm(struct path *path, int flags) { struct file *filp; int acc_mask = ("\004\002\006\006"[flags&O_ACCMODE]); /* ACC_MODE(open_to_namei_flags()) */ int err; err = cr_permission(path->dentry->d_inode, acc_mask); filp = ERR_PTR(err); if (!IS_ERR(filp)) { filp = cr_dentry_open(path, flags); } return filp; }
/* Call permision() and dentry_open(). * Caller should dget() and mntget() just as they would for dentry_open(). */ struct file * cr_dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) { struct file *filp; int acc_mask = ("\000\004\002\006"[(flags)&O_ACCMODE]); /* ICK (from linux/fs/namei.c) */ int err; err = cr_permission(dentry->d_inode, acc_mask, NULL); filp = ERR_PTR(err); #if HAVE_TASK_CRED if (!IS_ERR(filp)) filp = dentry_open(dentry, mnt, flags, cr_current_cred()); #else if (!IS_ERR(filp)) filp = dentry_open(dentry, mnt, flags); #endif return filp; }
// XXX: need comment here // XXX: currently only check perms to create here. // XXX: other checks needed? static int do_init_dir(cr_location_t *loc, struct file *dirp) { int result = 0; result = cr_permission(dirp->f_dentry->d_inode, (loc->is_write ? MAY_WRITE : MAY_READ) | MAY_EXEC, NULL); if (!result) { loc->fs = copy_fs_struct(current->fs); if (loc->fs) { // replace the pwd with that of 'dirp' cr_set_pwd_file(loc->fs, dirp); } else { result = -EINVAL; } } // Error and normal paths exit here fput(dirp); // We don't hold the filp for a directory return result; }