From: Valerie Aurora <valerie.aurora@gmail.com>
To: linux-fsdevel@vger.kernel.org, linux@vger.kernel.org
Cc: viro@zeniv.linux.org.uk, Valerie Aurora <vaurora@redhat.com>,
Valerie Aurora <valerie.aurora@gmail.com>
Subject: [PATCH 61/74] VFS: Split inode_permission() and create path_permission()
Date: Tue, 22 Mar 2011 19:04:52 -0700 [thread overview]
Message-ID: <1300845905-14433-18-git-send-email-valerie.aurora@gmail.com> (raw)
In-Reply-To: <1300845905-14433-1-git-send-email-valerie.aurora@gmail.com>
From: Valerie Aurora <vaurora@redhat.com>
Split inode_permission() into inode and file-system-dependent parts.
Create path_permission() to check permission based on the path to the
inode. This is for union mounts, in which an inode can be located on
a read-only lower layer file system but is still writable, since we
will copy it up to the writable top layer file system. So in that
case, we want to ignore MS_RDONLY on the lower layer. To make this
decision, we must know the path (vfsmount, dentry) of both the target
and its parent.
XXX - so ugly!
Signed-off-by: Valerie Aurora <valerie.aurora@gmail.com>
---
fs/namei.c | 92 ++++++++++++++++++++++++++++++++++++++++++++--------
include/linux/fs.h | 1 +
2 files changed, 79 insertions(+), 14 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 47fe25a..bf8d857 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -241,29 +241,20 @@ int generic_permission(struct inode *inode, int mask,
}
/**
- * inode_permission - check for access rights to a given inode
+ * __inode_permission - check for access rights to a given inode
* @inode: inode to check permission on
* @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
*
* Used to check for read/write/execute permissions on an inode.
- * We use "fsuid" for this, letting us set arbitrary permissions
- * for filesystem access without changing the "normal" uids which
- * are used for other things.
+ *
+ * This does not check for a read-only file system. You probably want
+ * inode_permission().
*/
-int inode_permission(struct inode *inode, int mask)
+static int __inode_permission(struct inode *inode, int mask)
{
int retval;
if (mask & MAY_WRITE) {
- umode_t mode = inode->i_mode;
-
- /*
- * 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.
*/
@@ -287,6 +278,79 @@ int inode_permission(struct inode *inode, int mask)
}
/**
+ * sb_permission - check superblock-level permissions
+ * @sb: superblock of inode to check permission on
+ * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ *
+ * Separate out file-system wide checks from inode-specific permission
+ * checks. In particular, union mounts want to check the read-only
+ * status of the top-level file system, not the lower.
+ */
+int sb_permission(struct super_block *sb, struct inode *inode, int mask)
+{
+ if (mask & MAY_WRITE) {
+ umode_t mode = inode->i_mode;
+
+ /*
+ * Nobody gets write access to a read-only fs.
+ */
+ if ((sb->s_flags & MS_RDONLY) &&
+ (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
+ return -EROFS;
+ }
+ return 0;
+}
+
+/**
+ * inode_permission - check for access rights to a given inode
+ * @inode: inode to check permission on
+ * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ *
+ * Used to check for read/write/execute permissions on an inode.
+ * We use "fsuid" for this, letting us set arbitrary permissions
+ * for filesystem access without changing the "normal" uids which
+ * are used for other things.
+ */
+int inode_permission(struct inode *inode, int mask)
+{
+ int retval;
+
+ retval = sb_permission(inode->i_sb, inode, mask);
+ if (retval)
+ return retval;
+ return __inode_permission(inode, mask);
+}
+
+/**
+ * path_permission - check for inode access rights depending on path
+ * @path: path of inode to check
+ * @parent_path: path of inode's parent
+ * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ *
+ * Like inode_permission, but used to check for permission when the
+ * file may potentially be copied up between union layers.
+ */
+
+int path_permission(struct path *path, struct path *parent_path, int mask)
+{
+ struct vfsmount *mnt;
+ int retval;
+
+ /* Catch some reversal of args */
+ BUG_ON(!S_ISDIR(parent_path->dentry->d_inode->i_mode));
+
+ if (IS_MNT_UNION(parent_path->mnt))
+ mnt = parent_path->mnt;
+ else
+ mnt = path->mnt;
+
+ retval = sb_permission(mnt->mnt_sb, path->dentry->d_inode, mask);
+ if (retval)
+ return retval;
+ return __inode_permission(path->dentry->d_inode, mask);
+}
+
+/**
* file_permission - check for additional access rights to a given file
* @file: file to check access rights for
* @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3dfb0e2..fe16edf 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2140,6 +2140,7 @@ extern sector_t bmap(struct inode *, sector_t);
#endif
extern int notify_change(struct dentry *, struct iattr *);
extern int inode_permission(struct inode *, int);
+extern int path_permission(struct path *, struct path *, int);
extern int generic_permission(struct inode *, int,
int (*check_acl)(struct inode *, int));
--
1.7.0.4
next prev parent reply other threads:[~2011-03-23 2:06 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-23 2:04 [PATCH 44/74] union-mount: Temporarily disable some syscalls Valerie Aurora
2011-03-23 2:04 ` [PATCH 45/74] union-mount: Basic infrastructure of __lookup_union() Valerie Aurora
2011-03-23 2:04 ` [PATCH 46/74] union-mount: Process negative dentries in __lookup_union() Valerie Aurora
2011-03-23 2:04 ` [PATCH 47/74] union-mount: Return files found in lower layers " Valerie Aurora
2011-03-23 2:04 ` [PATCH 48/74] union-mount: Build union stack " Valerie Aurora
2011-03-23 2:04 ` [PATCH 49/74] union-mount: Follow mount " Valerie Aurora
2011-03-23 2:04 ` [PATCH 50/74] union-mount: Add lookup_union() Valerie Aurora
2011-03-23 2:04 ` [PATCH 51/74] union-mount: Add do_lookup_union() wrapper for __lookup_union() Valerie Aurora
2011-03-23 2:04 ` [PATCH 52/74] union-mount: Call union lookup functions in lookup path Valerie Aurora
2011-03-23 2:04 ` [PATCH 53/74] union-mount: Create whiteout on unlink() Valerie Aurora
2011-03-23 2:04 ` [PATCH 54/74] union-mount: Create whiteout on rmdir() Valerie Aurora
2011-03-23 2:04 ` [PATCH 55/74] union-mount: Set opaque flag on new directories in unioned file systems Valerie Aurora
2011-03-23 2:04 ` [PATCH 56/74] union-mount: Copy up directory entries on first readdir() Valerie Aurora
2011-03-23 2:04 ` [PATCH 57/74] union-mount: Add generic_readdir_fallthru() helper Valerie Aurora
2011-03-23 2:04 ` [PATCH 58/74] fallthru: ext2 support for lookup of d_type/d_ino in fallthrus Valerie Aurora
2011-03-23 2:04 ` [PATCH 59/74] fallthru: tmpfs " Valerie Aurora
2011-03-23 2:04 ` [PATCH 60/74] fallthru: jffs2 " Valerie Aurora
2011-03-23 2:04 ` Valerie Aurora [this message]
2011-03-23 2:04 ` [PATCH 62/74] VFS: Create user_path_nd() to lookup both parent and target Valerie Aurora
2011-03-23 2:04 ` [PATCH 63/74] union-mount: In-kernel file copyup routines Valerie Aurora
2011-03-23 2:04 ` [PATCH 64/74] union-mount: Implement union-aware access()/faccessat() Valerie Aurora
2011-03-23 2:04 ` [PATCH 65/74] union-mount: Implement union-aware link() Valerie Aurora
2011-03-23 2:04 ` [PATCH 66/74] union-mount: Implement union-aware rename() Valerie Aurora
2011-03-23 2:04 ` [PATCH 67/74] union-mount: Implement union-aware writable open() Valerie Aurora
2011-03-23 2:04 ` [PATCH 68/74] union-mount: Implement union-aware chown() Valerie Aurora
2011-03-23 2:05 ` [PATCH 69/74] union-mount: Implement union-aware truncate() Valerie Aurora
2011-03-23 2:05 ` [PATCH 70/74] union-mount: Implement union-aware chmod()/fchmodat() Valerie Aurora
2011-03-23 2:05 ` [PATCH 71/74] union-mount: Implement union-aware lchown() Valerie Aurora
2011-03-23 2:05 ` [PATCH 72/74] union-mount: Implement union-aware utimensat() Valerie Aurora
2011-03-23 2:05 ` [PATCH 73/74] union-mount: Implement union-aware setxattr() Valerie Aurora
2011-03-23 2:05 ` [PATCH 74/74] union-mount: Implement union-aware lsetxattr() Valerie Aurora
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1300845905-14433-18-git-send-email-valerie.aurora@gmail.com \
--to=valerie.aurora@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux@vger.kernel.org \
--cc=vaurora@redhat.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).