From 3d5a6482fd89423b94d8bb3a0a303f0b40bb4279 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 9 Aug 2012 16:47:21 +0100 Subject: [PATCH 13/13] overlayfs: copy up i_uid/i_gid from the underlying inode Patch-mainline: not yet YAMA et al rely on on i_uid/i_gid to be populated in order to perform their checks. While these really cannot be guarenteed as the underlying filesystem may not even have the concept, they are expected to be filled when possible. To quote Al Viro: "Ideally, yes, we'd want to have ->i_uid used only by fs-specific code and helpers used by that fs (including those that are implicit defaults). [...] In practice we have enough places where uid/gid is used directly to make setting them practically a requirement - places like /proc// can get away with not doing that, but only because shitloads of syscalls are not allowed on those anyway, permissions or no permissions. In anything general-purpose you really need to set it." Copy up the underlying filesystem information into the overlayfs inode when we create it. Buglink: http://bugs.launchpad.net/bugs/944386 Signed-off-by: Andy Whitcroft Signed-off-by: Miklos Szeredi --- fs/overlayfs/dir.c | 2 ++ fs/overlayfs/inode.c | 2 ++ fs/overlayfs/overlayfs.h | 6 ++++++ fs/overlayfs/super.c | 1 + 4 files changed, 11 insertions(+) Index: linux-3.6-rc7-master/fs/overlayfs/dir.c =================================================================== --- linux-3.6-rc7-master.orig/fs/overlayfs/dir.c 2012-09-28 13:37:04.000000000 +0200 +++ linux-3.6-rc7-master/fs/overlayfs/dir.c 2012-09-28 13:37:10.000000000 +0200 @@ -304,6 +304,7 @@ static int ovl_create_object(struct dent } } ovl_dentry_update(dentry, newdentry); + ovl_copyattr(newdentry->d_inode, inode); d_instantiate(dentry, inode); inode = NULL; newdentry = NULL; @@ -446,6 +447,7 @@ static int ovl_link(struct dentry *old, new->d_fsdata); if (!newinode) goto link_fail; + ovl_copyattr(upperdir->d_inode, newinode); ovl_dentry_version_inc(new->d_parent); ovl_dentry_update(new, newdentry); Index: linux-3.6-rc7-master/fs/overlayfs/inode.c =================================================================== --- linux-3.6-rc7-master.orig/fs/overlayfs/inode.c 2012-09-28 13:37:08.000000000 +0200 +++ linux-3.6-rc7-master/fs/overlayfs/inode.c 2012-09-28 13:37:10.000000000 +0200 @@ -31,6 +31,8 @@ int ovl_setattr(struct dentry *dentry, s mutex_lock(&upperdentry->d_inode->i_mutex); err = notify_change(upperdentry, attr); + if (!err) + ovl_copyattr(upperdentry->d_inode, dentry->d_inode); mutex_unlock(&upperdentry->d_inode->i_mutex); return err; Index: linux-3.6-rc7-master/fs/overlayfs/overlayfs.h =================================================================== --- linux-3.6-rc7-master.orig/fs/overlayfs/overlayfs.h 2012-09-28 13:36:53.000000000 +0200 +++ linux-3.6-rc7-master/fs/overlayfs/overlayfs.h 2012-09-28 13:37:10.000000000 +0200 @@ -56,6 +56,12 @@ int ovl_removexattr(struct dentry *dentr struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, struct ovl_entry *oe); +static inline void ovl_copyattr(struct inode *from, struct inode *to) +{ + to->i_uid = from->i_uid; + to->i_gid = from->i_gid; +} + /* dir.c */ extern const struct inode_operations ovl_dir_inode_operations; Index: linux-3.6-rc7-master/fs/overlayfs/super.c =================================================================== --- linux-3.6-rc7-master.orig/fs/overlayfs/super.c 2012-09-28 13:37:00.000000000 +0200 +++ linux-3.6-rc7-master/fs/overlayfs/super.c 2012-09-28 13:37:10.000000000 +0200 @@ -347,6 +347,7 @@ static int ovl_do_lookup(struct dentry * oe); if (!inode) goto out_dput; + ovl_copyattr(realdentry->d_inode, inode); } if (upperdentry)