From: Alin Dobre <alinmd@xxxxxxxxx> UID-only mapping is now done properly for stat and read access functionalities. Signed-off-by: Alin Dobre <alinmd@xxxxxxxxx> --- fs/idmapfs/file.c | 6 ++++++ fs/idmapfs/inode.c | 6 ++++++ fs/idmapfs/lookup.c | 23 +++++++++++++++++++++++ fs/idmapfs/wrapfs.h | 9 ++++++++- 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/fs/idmapfs/file.c b/fs/idmapfs/file.c index 9825816..df44994 100644 --- a/fs/idmapfs/file.c +++ b/fs/idmapfs/file.c @@ -19,7 +19,9 @@ static ssize_t wrapfs_read(struct file *file, char __user *buf, struct dentry *dentry = file->f_path.dentry; lower_file = wrapfs_lower_file(file); + lower_file->f_inode->i_uid=map_id(lower_file->f_inode->i_uid); err = vfs_read(lower_file, buf, count, ppos); + lower_file->f_inode->i_uid=unmap_id(lower_file->f_inode->i_uid); /* update our inode atime upon a successful lower read */ if (err >= 0) fsstack_copy_attr_atime(dentry->d_inode, @@ -36,7 +38,9 @@ static ssize_t wrapfs_write(struct file *file, const char __user *buf, struct dentry *dentry = file->f_path.dentry; lower_file = wrapfs_lower_file(file); + lower_file->f_inode->i_uid=map_id(lower_file->f_inode->i_uid); err = vfs_write(lower_file, buf, count, ppos); + lower_file->f_inode->i_uid=unmap_id(lower_file->f_inode->i_uid); /* update our inode times+sizes upon a successful lower write */ if (err >= 0) { fsstack_copy_inode_size(dentry->d_inode, @@ -55,7 +59,9 @@ static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir) struct dentry *dentry = file->f_path.dentry; lower_file = wrapfs_lower_file(file); + lower_file->f_inode->i_uid=map_id(lower_file->f_inode->i_uid); err = vfs_readdir(lower_file, filldir, dirent); + lower_file->f_inode->i_uid=unmap_id(lower_file->f_inode->i_uid); file->f_pos = lower_file->f_pos; if (err >= 0) /* copy the atime */ fsstack_copy_attr_atime(dentry->d_inode, diff --git a/fs/idmapfs/inode.c b/fs/idmapfs/inode.c index d7fe145..2b80e00 100644 --- a/fs/idmapfs/inode.c +++ b/fs/idmapfs/inode.c @@ -23,8 +23,12 @@ static int wrapfs_create(struct inode *dir, struct dentry *dentry, lower_dentry = lower_path.dentry; lower_parent_dentry = lock_parent(lower_dentry); + lower_dentry->d_inode->i_uid = map_id(lower_dentry->d_inode->i_uid); + lower_parent_dentry->d_inode->i_uid = map_id(lower_parent_dentry->d_inode->i_uid); err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, want_excl); + lower_dentry->d_inode->i_uid = unmap_id(lower_dentry->d_inode->i_uid); + lower_parent_dentry->d_inode->i_uid = unmap_id(lower_parent_dentry->d_inode->i_uid); if (err) goto out; err = wrapfs_interpose(dentry, dir->i_sb, &lower_path); @@ -354,7 +358,9 @@ static int wrapfs_permission(struct inode *inode, int mask) int err; lower_inode = wrapfs_lower_inode(inode); + lower_inode->i_uid=map_id(lower_inode->i_uid); err = inode_permission(lower_inode, mask); + lower_inode->i_uid=unmap_id(lower_inode->i_uid); return err; } diff --git a/fs/idmapfs/lookup.c b/fs/idmapfs/lookup.c index fa6e019..999b227 100644 --- a/fs/idmapfs/lookup.c +++ b/fs/idmapfs/lookup.c @@ -103,6 +103,7 @@ struct inode *wrapfs_iget(struct super_block *sb, struct inode *lower_inode) struct inode *inode; /* the new inode to return */ int err; + lower_inode->i_uid=map_id(lower_inode->i_uid); inode = iget5_locked(sb, /* our superblock */ /* * hashval: we use inode number, but we can @@ -202,7 +203,9 @@ int wrapfs_interpose(struct dentry *dentry, struct super_block *sb, */ /* inherit lower inode number for wrapfs's inode */ + lower_inode->i_uid=map_id(lower_inode->i_uid); inode = wrapfs_iget(sb, lower_inode); + lower_inode->i_uid=unmap_id(lower_inode->i_uid); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto out; @@ -330,3 +333,23 @@ out: dput(parent); return ret; } + +/* + * Maps the id received as parameter, from 1000 to 1001. + * Can be used for both UID and GID mapping. + */ +int map_id(int id) { + if (id == 1000) return 1001; + return id; +} + +/* + * Maps back the id received as parameter, from 1001 to 1000. + * Can be used for both UID and GID backwards mapping. + */ +int unmap_id(int id) { + if (id == 1001) return 1000; + return id; +} + + diff --git a/fs/idmapfs/wrapfs.h b/fs/idmapfs/wrapfs.h index a85b07e..59f46bc 100644 --- a/fs/idmapfs/wrapfs.h +++ b/fs/idmapfs/wrapfs.h @@ -60,6 +60,10 @@ extern struct inode *wrapfs_iget(struct super_block *sb, extern int wrapfs_interpose(struct dentry *dentry, struct super_block *sb, struct path *lower_path); +/* UID/GID mapping */ +int map_id(int id); +int unmap_id(int id); + /* file private data */ struct wrapfs_file_info { struct file *lower_file; @@ -92,7 +96,10 @@ struct wrapfs_sb_info { */ static inline struct wrapfs_inode_info *WRAPFS_I(const struct inode *inode) { - return container_of(inode, struct wrapfs_inode_info, vfs_inode); + struct wrapfs_inode_info *i; + i = container_of(inode, struct wrapfs_inode_info, vfs_inode); + i->vfs_inode.i_uid = map_id(i->vfs_inode.i_uid); + return i; } /* dentry to private data */ -- 1.8.3.2 _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies