ovl: override creds with the ones from the superblock mounter
[linux-2.6-block.git] / fs / overlayfs / super.c
index 791235e03d1712ed92b62bc405483dd2e1ab972b..d659f766ceff7288ec86b57f026ec2dee3c64110 100644 (file)
@@ -42,6 +42,8 @@ struct ovl_fs {
        long lower_namelen;
        /* pathnames of lower and upper dirs, for show_options */
        struct ovl_config config;
+       /* creds of process who forced instantiation of super block */
+       const struct cred *creator_cred;
 };
 
 struct ovl_dir_cache;
@@ -265,6 +267,13 @@ bool ovl_is_whiteout(struct dentry *dentry)
        return inode && IS_WHITEOUT(inode);
 }
 
+const struct cred *ovl_override_creds(struct super_block *sb)
+{
+       struct ovl_fs *ofs = sb->s_fs_info;
+
+       return override_creds(ofs->creator_cred);
+}
+
 static bool ovl_is_opaquedir(struct dentry *dentry)
 {
        int res;
@@ -603,6 +612,7 @@ static void ovl_put_super(struct super_block *sb)
        kfree(ufs->config.lowerdir);
        kfree(ufs->config.upperdir);
        kfree(ufs->config.workdir);
+       put_cred(ufs->creator_cred);
        kfree(ufs);
 }
 
@@ -1108,10 +1118,14 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        else
                sb->s_d_op = &ovl_dentry_operations;
 
+       ufs->creator_cred = prepare_creds();
+       if (!ufs->creator_cred)
+               goto out_put_lower_mnt;
+
        err = -ENOMEM;
        oe = ovl_alloc_entry(numlower);
        if (!oe)
-               goto out_put_lower_mnt;
+               goto out_put_cred;
 
        root_dentry = d_make_root(ovl_new_inode(sb, S_IFDIR, oe));
        if (!root_dentry)
@@ -1144,6 +1158,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 
 out_free_oe:
        kfree(oe);
+out_put_cred:
+       put_cred(ufs->creator_cred);
 out_put_lower_mnt:
        for (i = 0; i < ufs->numlower; i++)
                mntput(ufs->lower_mnt[i]);